Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.04.2008, 14:16   #1
mat90x
Пользователь
 
Аватар для mat90x
 
Регистрация: 19.04.2008
Сообщений: 22
Восклицание C++.Visual Studio 2005.WinApp.Работа с ListBox

Помогите пожайлуста студенту првого курса уже больше недели никак не могу решить эту задачу из-за одной ошибки!

Задача: пользователь вводит через диалог фамилию, имя и гол рождения студента. Программа расчитывает возраст студента и записывает его в список, так, чтобы его можно было просмотреть. В программе есть необходимые комментарии, думаю разберетесь!


Ошибка: в режиме Debug, после ввода информации в диалог и нажатия кнопки OK программа вылетает и возникает ошибка, где проверяется уловие studBeg.godRojd:
if(studBeg.godRojd)
let = (newtime.tm_year + 1900) - studBeg.godRojd; //(текущий г. + 1990 г.) - г. рождения студента


Сама ошибка:
Unhandled exception at 0x0041162e in martirosyna_5_Nishna.exe: 0xC0000005: Access violation reading location 0x00200084.

Изивните, но мне не удалось выложить этот проект на форуме, так что я его выложил на depositfiles:
http://depositfiles.com/files/4839704

P. S.: заранее всем благодарен!
mat90x вне форума Ответить с цитированием
Старый 19.04.2008, 15:52   #2
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

Цитата:
Сообщение от mat90x Посмотреть сообщение
Ошибка: в режиме Debug, после ввода информации в диалог и нажатия кнопки OK программа вылетает и возникает ошибка, где проверяется уловие studBeg.godRojd:
if(studBeg.godRojd)
let = (newtime.tm_year + 1900) - studBeg.godRojd; //(текущий г. + 1990 г.) - г. рождения студента
Ну и где в том, что Вы выложили такая строка? Выложите свой код нормально, текстом, прямо сюда.
B_N вне форума Ответить с цитированием
Старый 19.04.2008, 16:20   #3
mat90x
Пользователь
 
Аватар для mat90x
 
Регистрация: 19.04.2008
Сообщений: 22
По умолчанию

Цитата:
Сообщение от B_N Посмотреть сообщение
Ну и где в том, что Вы выложили такая строка? Выложите свой код нормально, текстом, прямо сюда.
она находиться в файле martirosyan_5_obrabotka.cpp в функции obrabotkaInfo!

#include "stdafx.h"
#include "martirosyna_5_Nishna.h"
void Clear(Union& u)
//функция в строке u.str по адресам NF - 1 и NF + NI - 1 вставляет символ '|'
{
int len = sizeof(u.str)/sizeof(char);
for (int i = 0; i < len; i++)
if (i == NF - 1 || i == NF + NI - 1)
u.str[i] = '|';
else u.str[i] = ' ';
}
Union obrabotkaInfo(const StudBeg& studBeg)
//функция получает фамилию, имя и год рождения студента через studBeg
//и записывает в StudEnd фамилию, имя и его возраст
{
Union u;
Clear(u);
//получить текущую дату - текущий год newtime.tm_year + 1900
//смотрите в Help пример применения функции _localtime64_s
char buf[26];
time_t ltime; //ltime может хранит системную дату
time( &ltime ); //Запись системного времени в ltime
errno_t err = ctime_s( buf, 26, &ltime ); //Преобразовывает значение времени в строку и прикрепляет к локальным
//настройкам временной зоны
//struct tm
tm newtime; //структура, содержащая единицы времени и их значение(секунды, минуты, часы...)
_localtime64_s( &newtime, &ltime ); //Преобразовывает значение времени и корректирует для данного часого пояса
//Записывает данное время из ltime в newtime
int let = 0; //возраст студента
//вычисление возраста относительно текущего года
if(studBeg.godRojd)
let = (newtime.tm_year + 1900) - studBeg.godRojd; //(текущий г. + 1990 г.) - г. рождения студента

//запись информации о студенте в новом виде
TCHAR bufLet[3];
if(let > 0 && studBeg.godRojd >= 1970)
{
wcsncpy(u.studEnd.fam, studBeg.fam, wcslen(studBeg.fam));
wcsncpy(u.studEnd.imia, studBeg.imia, wcslen(studBeg.imia));
swprintf(u.studEnd.let, wcslen(u.studEnd.let), L"%i", let);
}
return u;
}
mat90x вне форума Ответить с цитированием
Старый 19.04.2008, 17:37   #4
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

Вот эта строка:
Код:
int len = sizeof(u.str)/sizeof(char);
у Вас стэк убивает, вместе с передаваемой в obrabotkaInfo ссылкой. char нужно заменить на TCHAR или wchar_t, смотря с чем работаете. Вообще внимательно пройдите по программе и поправьте все такие места, их там гора. Если работаете через постановку (TCHAR), поскольку изначально так типы объявлены, значит соответственно меняйте wcsncpy на _tcsncpy и т.д. Плюс ещё кое-какие мелочи, скажем неправильно проверяется возврат из диалога IDD_ADD_REC. И IDOK, и IDCANCEL вот здесь
Код:
			if (dlgYes)
			{
				itemU = obrabotkaInfo(studBeg);//получили преобразовнную строку
				SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM) itemU.str);//записали ее в список 
			}
будут определяться, как истина - смысл проверки теряется. И пользуйтесь отладчиком. Если после исправлений глюки останутся - показывайте снова.
B_N вне форума Ответить с цитированием
Старый 19.04.2008, 18:40   #5
mat90x
Пользователь
 
Аватар для mat90x
 
Регистрация: 19.04.2008
Сообщений: 22
По умолчанию

Цитата:
Сообщение от B_N Посмотреть сообщение
Вот эта строка:
Код:
int len = sizeof(u.str)/sizeof(char);
у Вас стэк убивает, вместе с передаваемой в obrabotkaInfo ссылкой. char нужно заменить на TCHAR или wchar_t, смотря с чем работаете.
исправил это место на
Код:
int len = sizeof(u.str)/sizeof(TCHAR);
Ошибка возникла по моей глупости! Я сначала эту функцию делал в консоли, а потом уже в Windows переводил и забыл поменять! Впредь буду повнимательней!
И некоторые вопросы:

Цитата:
Если работаете через постановку (TCHAR), поскольку изначально так типы объявлены, значит соответственно меняйте wcsncpy на _tcsncpy и т.д.
тоесть для wchar_t ипользуется функция wcsncpy, а для TCHAR _tcsncpy?
Но ведь для TCHAR может использоваться и wcsnpy! Нужно ли менять функции или это не так строго?

Цитата:
Плюс ещё кое-какие мелочи, скажем неправильно проверяется возврат из диалога IDD_ADD_REC. И IDOK, и IDCANCEL вот здесь
а как тогда должна вынлядеть функция?
Вот так?
Код:
BOOL CALLBACK GetDataDlgProc(HWND hdlg, UINT message, WPARAM wparam, LPARAM lparam)
{
	BOOL lpGod;
	switch(message)
	{
	case WM_INITDIALOG:
			SetFocus(GetDlgItem(hdlg, IDC_GET_FAM));
			return FALSE;
	case WM_COMMAND:
		switch(LOWORD(wparam))
		{
		case IDOK:
			GetDlgItemText(hdlg, IDC_GET_FAM, studBeg.fam, 30);
			GetDlgItemText(hdlg, IDC_GET_IMIA, studBeg.imia, 20);
			studBeg.godRojd = GetDlgItemInt(hdlg, IDC_GET_GOD, &lpGod, FALSE);
			EndDialog(hdlg, TRUE);
			return TRUE;
		case IDCANCEL:
			EndDialog(hdlg, FALSE);
			return FALSE;
		}
		break;
	}
	return FALSE;
}
mat90x вне форума Ответить с цитированием
Старый 19.04.2008, 20:47   #6
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

[QUOTE=mat90x;92279]исправил это место на
Код:
int len = sizeof(u.str)/sizeof(TCHAR);
Ошибка возникла по моей глупости! Я сначала эту функцию делал в консоли, а потом уже в Windows переводил и забыл поменять! Впредь буду повнимательней!


Цитата:
Сообщение от mat90x Посмотреть сообщение
тоесть для wchar_t ипользуется функция wcsncpy, а для TCHAR _tcsncpy?
Но ведь для TCHAR может использоваться и wcsnpy! Нужно ли менять функции или это не так строго?
Дело не в том, что это строго, а в том, что TCHAR, _tcsncpy и вообще все эти _t***, так же как и большинство объявлений функций API на самом деле макросы, которые в зависимости от того, включен ли юникод для проекта будут либо либо обычными char'ами и функциями, работающими с char'ом, либо wchar_t'ами и соответственно функциями, работающими с wchar_t'ом. Естественно, нет никакого запрета на то, чтобы их перемешивать в проекте как заблагорассудится, но только в том случае, если Вы знаете, что делаете, иначе, смотря по тому, компилируется проект под юникод или нет, полезет масса ошибок, и хорошо ещё если при компиляции. Например в явно объявленную юникод-версию функции, как в Вашем случае, пойдет обычный char, или наоборот, или такая же беда как с вычислением длины строки, как у Вас выше.


Цитата:
Сообщение от mat90x Посмотреть сообщение
а как тогда должна вынлядеть функция?
Здесь я имел в виду именно вот эту проверку:
Код:
			if (dlgYes)
			{
				itemU = obrabotkaInfo(studBeg);//получили преобразовнную строку
				SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM) itemU.str);//записали ее в список 
			}
Поменяйте условие на
Код:
if (IDOK == dlgYes) {..........}
вдруг впоследствии захотите добавить ещё кнопки к диалогу. А в EndDialog просто передавайте LOWORD(wparam).
Код:
EndDialog(hdlg, LOWORD(wparam));
Я, наверное, просто не заметил, что Вы вызываете его с FALSE или TRUE в зависимости от результата, так что зря Вас озадачил.
B_N вне форума Ответить с цитированием
Старый 19.04.2008, 21:03   #7
mat90x
Пользователь
 
Аватар для mat90x
 
Регистрация: 19.04.2008
Сообщений: 22
По умолчанию

Цитата:
Дело не в том, что это строго, а в том, что TCHAR, _tcsncpy и вообще все эти _t***, так же как и большинство объявлений функций API на самом деле макросы, которые в зависимости от того, включен ли юникод для проекта будут либо либо обычными char'ами и функциями, работающими с char'ом, либо wchar_t'ами и соответственно функциями, работающими с wchar_t'ом. Естественно, нет никакого запрета на то, чтобы их перемешивать в проекте как заблагорассудится, но только в том случае, если Вы знаете, что делаете, иначе, смотря по тому, компилируется проект под юникод или нет, полезет масса ошибок, и хорошо ещё если при компиляции. Например в явно объявленную юникод-версию функции, как в Вашем случае, пойдет обычный char, или наоборот, или такая же беда как с вычислением длины строки, как у Вас выше.
тоесть INICODE или ASCII могут храниться и в "узких" и "широких" строках, а будет ли это UNICODE или ASCII зависит от того в какой среде я пишу программу?

Извините за ламерство, но я еще только примерно 2 месяца программирую под Windows! Но что значит LOWORD(wparam)? Кроме как "младшее слово из wparam" и то что там храняться коды сообщений я ничего не знаю!
mat90x вне форума Ответить с цитированием
Старый 19.04.2008, 23:11   #8
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

Цитата:
Сообщение от mat90x Посмотреть сообщение
тоесть INICODE или ASCII могут храниться и в "узких" и "широких" строках, а будет ли это UNICODE или ASCII зависит от того в какой среде я пишу программу?
Не совсем так. В каком виде хранятся - вопрос важный, но не самый важный. В конце концов, это всего лишь массивы, один char strA[], другой - short strW[], хотя, разумеется, представление символов различно. Важно какие функции вызываются над этими данными, и здесь не должно быть путаницы.

Цитата:
Сообщение от mat90x Посмотреть сообщение
Извините за ламерство, но я еще только примерно 2 месяца программирую под Windows! Но что значит LOWORD(wparam)? Кроме как "младшее слово из wparam" и то что там храняться коды сообщений я ничего не знаю!
В нижней половине wParam по WM_COMMAND приходит идентификатор контрола, отправившего команду, в данном случае это и будут IDOK и IDCANCEL. И считается правильным, если в EndDialog будет передаваться команда, "закрывающая" диалог, с тем, чтобы можно было определить результат вызова самого диалога.
B_N вне форума Ответить с цитированием
Старый 20.04.2008, 16:23   #9
mat90x
Пользователь
 
Аватар для mat90x
 
Регистрация: 19.04.2008
Сообщений: 22
По умолчанию

Хорошо, и еще последний вопрос: чем отличается режим Debug от режима Release? Почему в Debug происходят ошибки, а в Release такие ошибки не происходят?
mat90x вне форума Ответить с цитированием
Старый 20.04.2008, 23:51   #10
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

Цитата:
Сообщение от mat90x Посмотреть сообщение
Хорошо, и еще последний вопрос: чем отличается режим Debug от режима Release? Почему в Debug происходят ошибки, а в Release такие ошибки не происходят?
На самом деле это очень обширный вопрос, достойный отдельной темы, тем более, что один вопрос - одна тема. Если кратко, то это практически полностью разные режимы компиляции - используются разные функции и структуры данных для управления памятью - даже операторы new и delete - разные, в режиме DEBUG работает множество отладочных функций и макросов, вроде ASSERT, даже dll-библиотеки линкуются разные. А с другой стороны, это всё реализовано просто с помощью условной компиляции - директивами #define, #ifdef и т.д. А ошибки могут независимо друг от друга появляться то в отладочном, то в финальном варианте, смотря, что за ошибки.
B_N вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Visual Studio 2005 amelie Win Api 19 06.09.2008 12:40
visual studio.net 2005 zub Помощь студентам 1 11.03.2008 07:29
Помогите с Visual Studio 2005 Поночка Visual C++ 1 08.03.2008 15:34
Visual studio 2005 и C++ oleg kutkov Visual C++ 7 09.01.2008 20:18
visual studio 2005 }{@KeRnutyi Свободное общение 1 30.10.2007 15:36