Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RusFAQ.ru: Программирование на C / C++


Информационный Канал Subscribe.Ru


RusFAQ.ru: Программирование на C / C++

Выпуск № 258
от 17.05.2003, 11:10

Администратор:
Имя: Nick.Box
URL: Информационный ресурс
ICQ: 365124
[censored], [censored]
О рассылке:
Задано вопросов: 776
Отправлено ответов: 1737
Активность: 223.8 %
[Задать вопрос >>][Регистрация эксперта >>]
[Поиск в базе][Обсудить на форуме]


 Список экспертов, ответы которых опубликованы в данном выпуске

Knignick
Статус: Доверительный
Общий рейтинг: 113.15
[Подробней >>]
baldr
Статус: Профессиональный
Общий рейтинг: 112.47
URL: Сайт об ОС DOS. Всем, кто любит эту ОС!
[Подробней >>]
Avl2k
Статус: Опытный
Общий рейтинг: 125.1
[Подробней >>]
 
DiGiT[old]
Статус: Профессиональный
Общий рейтинг: 111.62
[Подробней >>]
Chorkov
Статус: Начальный
Общий рейтинг: 111.76
[Подробней >>]
Shurik
Статус: Доверительный
Общий рейтинг: 136.36
[Подробней >>]
 
xiron
Статус: Доверительный
Общий рейтинг: 112.94
[Подробней >>]
BOLT
Статус: Доверительный
Общий рейтинг: 160.46
[Подробней >>]
Pin
Статус: Доверительный
Общий рейтинг: 125.65
[Подробней >>]
 
vitya
Статус: Профессиональный
Общий рейтинг: 108.07
[Подробней >>]
Yuri Gordienko
Статус: Опытный
Общий рейтинг: 115.51
[Подробней >>]
Ramzes
Статус: Опытный
Общий рейтинг: 127.81
URL: Microsoft homepage
[Подробней >>]
 
VicSimon
Статус: Доверительный
Общий рейтинг: 102.46
[Подробней >>]
Hayk
Статус: Начальный
Общий рейтинг: 107.5
[Подробней >>]
Илья
Статус: Опытный
Общий рейтинг: 103.76
[Подробней >>]
 
Andrew Vext
Статус: Опытный
Общий рейтинг: 106.05
[Подробней >>]


 Краткий перечень вопросов

Вопрос № 764. Для изучения читаю и пробую упражнения из книги Д. Рассохина "От Си к Си++". В одном упраж... (ответов: 8)
Вопрос № 765. Как можно убить статическую переменную, когда она уже не нужна? Спасибо!... (ответов: 7)
Вопрос № 766. Здраствуйте. Подскажите пожалуйста: Как с помощью WinApi добратьсь до эл-та меню и сделать его напри... (ответов: 5)
Вопрос № 767. Здравствуйте ув. Эксперты! ОС Win Xp Нужно перевести время на 1 час назад. Пишу SYSTEMTIME s,d; GetS... (ответов: 8)

Вопросов: 4, ответов: 28


 Вопрос № 764

Для изучения читаю и пробую упражнения из книги Д. Рассохина "От Си к Си++". В одном упражнении есть такая конструкция:
cout<где char *s; //указатель на строку.
И все работает, пока s не инициализируется значением NULL. Когда такое происходит, то “WindowNT 4.0 Workstation Rus” выдает сообщение:
"... обратилась по адресу 0х00000000. Память не может быть "read".
Как можно решить этот вопрос. Единственное, что у меня получилось, это заменить эту конструкцию на:
printf("%s ",s)
но хотелось бы узнать почему не работает у меня конструкция, данная в книге (хотя до этого все упражнения, на удивление, работали). И как сделать чтобы работала конструкция cout<С уважением, Александр.



Вопрос отправлен: 13.05.2003, 11:17
Отправитель: Alexander

[Следующий вопрос >>] [Список вопросов]

Отвечает Knignick

Доброе время суток, Alexander!
NULL - это пустой указатель, он не указывает ни на какие данные, если передавать его там где требуются адреса реальных данных то ошибки могут возникнуть не только в cout.
Все зависит от того, проверяет процедура свои параметры на корректность или нет. Если хочешь чтобы у тебя "не вылетал" этот пример можешь попробовать использовать обработку исключений:
try { cout < c; } catch(...) { cout < "Output error occured"; }
В конце концов можно перегрузить операторы <, <<, >, >>


Ответ отправлен: 13.05.2003, 12:01
Отправитель: Knignick


Отвечает baldr

Приветствую Вас, Alexander!
Так зачем же ты обнуляешь указатель? Конечно, по 0x0000 ничего нельзя читать! Для чтения через указатель его необходимо инициализировать.

Ответ отправлен: 13.05.2003, 12:53
Отправитель: baldr


Отвечает Avl2k

Здравствуйте, Alexander!
А как оно должно работать? По стандарту C++ указатель, передаваемый в operator << не должен быть нулевым (не путайте с "пустой" строкой "\0") - так что все не работает так, как надо :).
С уважением, Avl2k.

Ответ отправлен: 13.05.2003, 12:38
Отправитель: Avl2k


Отвечает DiGiT[old]

Добрый день, Alexander!
Видишь s В данном случае является переменной хранящей адрес начала первого элемента строки, константа NULL во многих компиляторах определена как 0 приведенный к типу указателя. Таким образом записав в s значение NULL ты пытаешься обратиться к области памяти, которая не принадлежит твоей программе, что вызывает ошибку обращения. Вообще разыменование указателя NULL не является разрешенным. а конструкция типа cout<<С будет работать если в качестве параметра ты будешь передавать реальный указатель.

Ответ отправлен: 14.05.2003, 06:40
Отправитель: DiGiT[old]


Отвечает Chorkov

Приветствую Вас, Alexander!
Прежде всего, передача потоку вывода нулевого указателя, является нештатной ситуацией, и ее не следует допускать.
Проблема использования не инициализированного указателя может быть решена несколькими способами:
1) Проверять указатель перед использованием:
cout<<( s==NULL ? L“ <> ” : s);
достоинство: Простота перехода от С-кода к С++ коду
недостаток: если тип переменной s будет изменен, то придется переписат большей обем кода.
2) Проверка перед использованием может быть замаскирована, чтобы избавиться от зависимости от типа переменной S:
template
inline const X FilterNullPtr(const X& x)
{return x;};
inline const char* FilterNullPtr(const char* x)
{return x==NULL ? " <> " : x;};
inline char* FilterNullPtr(char* x)
{return x==NULL ? " <> " : x;};
….
cout<< FilterNullPtr(s);
3) Отказаться от использования char* в пользу стандартных строк
#include
#include
using namespace std;

string s;
cout<(Они инициализируются пустой строкой, и потому, всегда валидны).
4) Обрабатывать исключение, возникающие при обращении по нулевому указателю.
int main(int,char**)
{
char*s=NULL;
try{
cout< }
catch(...)
{
return 1;
};
return 0;
};
Последний способ может быть рекомендован, только если появление неправильного или нулевого указателя является нештатной ситуацией, и ничего разумного, кроме сохранения данных и завершения приложения, сделать уже нельзя.
P.S.
К сожалению, выбранная вами книга (1993г), вышла еще до принятия современной редакции стандарта языка C++, поэтому многие очень важные возможности языка (такие как, обработка исключений, частичная параметризация шаблонов, анонимные пространства имен, STL) в данной книге не рассмотрены. Пока не поздно, советую сменить учебник, после, привыкнув к char*, переучиваться будет труднее.


Ответ отправлен: 13.05.2003, 14:26
Отправитель: Chorkov


Отвечает Shurik

Добрый день, Alexander!
Читайте не указатель на строку, а саму строку, т.е. без *


Ответ отправлен: 16.05.2003, 16:17
Отправитель: Shurik


Отвечает xiron

Добрый день, Alexander!
Во первых правильно писать так
#include
char *buf = "Сдесь могла бы быть ваша рекламма";
cout << buf;
"... обратилась по адресу 0х00000000. Память не может быть "read" - ну скорее всего после инициализации NULL -ом его никто и не меняет.
Хоть бы исходниками кинулся, для более конкретного ответа.
Наверное в книге опечатка.

Ответ отправлен: 14.05.2003, 16:25
Отправитель: xiron


Отвечает BOLT

Приветствую Вас, Alexander!
"cout<где char *s; //указатель на строку." - это вообще как понимать, друг?Я чего-то в это синктасисе не догоняю!Пиши точнее, я то типа - "У меня машина не хочет заводится.Не подскажете в чем проблема?" :-)
Счачтливо!

Ответ отправлен: 14.05.2003, 16:35
Отправитель: BOLT


 Вопрос № 765

Как можно убить статическую переменную, когда она уже не нужна?
Спасибо!



Вопрос отправлен: 13.05.2003, 21:43
Отправитель: Quas

[Следующий вопрос >>] [Список вопросов]

Отвечает BOLT

Добрый день, Quas!
Из моих знаний следует, что это невозможно.

Ответ отправлен: 13.05.2003, 22:03
Отправитель: BOLT


Отвечает Shurik

Здравствуйте, Quas!
Используйте динамическую или указатель на функцию с ее использованием


Ответ отправлен: 16.05.2003, 16:22
Отправитель: Shurik


Отвечает Pin

Добрый день, Quas!
Никак, на то она и статическая.

Ответ отправлен: 14.05.2003, 00:06
Отправитель: Pin


Отвечает vitya

Здравствуйте, Quas!
Увы никак.
В лучшем случае ты можешь создать статический указатель, а потом его delete тогда всего-лишь 4 байта у тебя будет занято памяти.

Ответ отправлен: 14.05.2003, 08:33
Отправитель: vitya


Отвечает Yuri Gordienko

Доброе время суток, Quas!
Никак, на то она и статическая. Под словом "убить" я понимаю освободить занимаемую переменной память.
Удачи


Ответ отправлен: 14.05.2003, 10:23
Отправитель: Yuri Gordienko


Отвечает Avl2k

Добрый день, Quas!
Статические переменные убиваются автоматически при завершении программы. Если в Вашей программе наступает момент, когда переменная не нужна, значит по смыслу она не является статической и надо несколько перепроектировать код, например передавать ее параметром.
С уважением, Avl2k.

Ответ отправлен: 14.05.2003, 10:54
Отправитель: Avl2k


Отвечает Ramzes

Добрый день, Quas!
Никак.
Статические переменные "живут" в области для глобальных переменных.

Ответ отправлен: 14.05.2003, 12:12
Отправитель: Ramzes


 Вопрос № 766

Здраствуйте. Подскажите пожалуйста:
Как с помощью WinApi добратьсь до эл-та меню и сделать
его например CHECKED.
Т.е не в rc файле, а программно.



Вопрос отправлен: 14.05.2003, 00:45
Отправитель: splash

[Следующий вопрос >>] [Список вопросов]

Отвечает VicSimon

Приветствую Вас, splash!
HMENU mHandle;
MENUITEMINFO mi;
mHandle = GetMenu (hWnd);
mi.cbSize = sizeof (MENUITEMINFO);
mi.fMask = MIIM_STATE;
mi.fState = MFS_CHECKED;
SetMenuItemInfo (mHandle, ITEM_ID, FALSE, &mi);
ITEM_ID - идентификатор пункта меню.
Более подробно см. SetMenuItemInfo, GetMenu и MENUITEMINFO в MSDN.

Ответ отправлен: 14.05.2003, 07:30
Отправитель: VicSimon


Отвечает baldr

Приветствую Вас, splash!
Смотри в приложении для MFC-шного CheckBox-а.

Приложение:

Ответ отправлен: 14.05.2003, 08:52
Отправитель: baldr


Отвечает Avl2k

Добрый день, splash!
Можно воспользоваться более простой функцией CheckMenuItem, либо более мощной SetMenuItemInfo. Пример:
void CheckMenuItemSample( HMENU hMenu )
{
CheckMenuItem( hMenu, ID_APP_EXIT, MF_BYCOMMAND | MF_CHECKED );
MENUITEMINFO mii;
memset( &mii, 0, sizeof(mii) );
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STATE;
mii.fState = MFS_CHECKED;
SetMenuItemInfo( hMenu, ID_FILE_NEW, FALSE/*не по номеру элемента, а по ID*/, &mii );
}
С уважением, Avl2k.

Ответ отправлен: 14.05.2003, 10:36
Отправитель: Avl2k


Отвечает Hayk

Приветствую Вас, splash!
Ispol'zyite funkcii GetMenu() , GetMenuItemInfo() i SetMenuItemInfo().

Ответ отправлен: 14.05.2003, 12:09
Отправитель: Hayk


Отвечает Ramzes

Здравствуйте, splash!
ON_UPDATE_COMMAND_UI(ID_ITEM, OnUpdate);

void OnUpdate(CCmdUI* pCmdUI)
{
pCmdUI->Enable(TRUE);
pCmdUI->SetCheck(1);
}

Ответ отправлен: 14.05.2003, 12:14
Отправитель: Ramzes


 Вопрос № 767

Здравствуйте ув. Эксперты!
ОС Win Xp
Нужно перевести время на 1 час назад.
Пишу
SYSTEMTIME s,d;
GetSystemTime(&d)
s.wHour=d.wHour-1;
SetSystemTime(&s);
Но время не переводится
Почем?
p.s. Уймите Knignika а то он без году неделя эксперт а уже
грубить начинает.



Вопрос отправлен: 14.05.2003, 07:56
Отправитель: m0v8lack

[Следующий вопрос >>] [Список вопросов]

Отвечает Илья

Приветствую Вас, m0v8lack!
Работает:
SYSTEMTIME d;
GetSystemTime(&d);
d.wHour -=1;
SetSystemTime(&d);

Ответ отправлен: 14.05.2003, 21:10
Отправитель: Илья


Отвечает Knignick

Приветствую Вас, m0v8lack!
Если в 9X работает, а в XP - нет, могу предположить, что это связано с привилегиями. Конкретно с SE_SYSTEMTIME_NAME, по дефолту она не установлена, ее можно установить с помощью AdjustTokenPrivileges().
Кстати, кому я нагрубил? Вроде ничего обидного не писал?
Уточните, пожалуйста, мылом - я извинюсь.


Ответ отправлен: 14.05.2003, 08:31
Отправитель: Knignick


Отвечает Yuri Gordienko

Добрый день, m0v8lack!
Возможно, у Вас нет привилегий изменять время. Но по приведенному примеру видно, что структура s содержит полный мусор, кроме часов(если я не ошибаюсь, то функция SetSystemTime контролирует корректность значений параметров). Поэтому уберите s вообще, а часы изменяйте на структуре d. А вообще, правильнее сначала проверять привилегии на подобные системные действия.
Удачи


Ответ отправлен: 14.05.2003, 10:20
Отправитель: Yuri Gordienko


Отвечает Avl2k

Здравствуйте, m0v8lack!
По идее должно работать. Возможно у того account'а, под которым вы запускаете программу, нет прав на перевод системного времени. Точнее можно узнать так: убедиться, что SetSystemTime вернула 0 и посмотреть код ошибки GetLastError() в разделе MSDN "Win32 Error Codes" (или прямо в MSDEV через QuickWatch, набрав в качестве выражения "код,hr" без кавычек.
С уважением, Avl2k.

Ответ отправлен: 14.05.2003, 10:47
Отправитель: Avl2k


Отвечает Andrew Vext

Доброе время суток, m0v8lack!
Попробуйте проверить права учетной записи из-под которой выполняется программа (есть ли право изменять системное время).

Ответ отправлен: 14.05.2003, 11:59
Отправитель: Andrew Vext


Отвечает Hayk

Здравствуйте, m0v8lack!
Otsutstvuyet inicializaciya strukturi "s". Strukturu "d" inicializirovala funkciya GetSystemTime, a kto doljen delat' eto dlya "d" ? U tebya tam v polyax chert ego znayet chto tvoritsya ... vot i ne rabotayet.

Ответ отправлен: 14.05.2003, 12:12
Отправитель: Hayk


Отвечает xiron

Здравствуйте, m0v8lack!
Дело в том что ты используеш 2 переменные
SYSTEMTIME s,d
в d записываеш GetSystemTime(&d)
s.wHour=d.wHour-1; меняеш только поле wHour и не копируеш другие поля.
А вообще то можно было бы обойтись и ондной переменной.
SYSTEMTIME time;
GetSystemTime(&time);
time.wHour = time.wHour - 1;
SetSystemTime(&time);

Ответ отправлен: 14.05.2003, 16:43
Отправитель: xiron


Отвечает BOLT

Доброе время суток, m0v8lack!
Э такая фишка в Windows-NT based не катит.Ты наверное использушь Windows2000/XP.Но, как говорил...не помню кто - не все потеряно:
Использую api-функцию для смены системных привелегий
BOOL AdjustTokenPrivileges(
HANDLE TokenHandle, privileges
BOOL DisableAllPrivileges,
PTOKEN_PRIVILEGES NewState,
DWORD BufferLength,
PTOKEN_PRIVILEGES PreviousState,
PDWORD ReturnLength
);
Меняешь время, потом ставишь привелегия наместо!
Вот и все.
Счастливо, друг!

Ответ отправлен: 14.05.2003, 22:35
Отправитель: BOLT



Форма отправки вопроса

Внимание!
Мы рекомендуем открывать рассылку в программе Internet Explorer 5.0+ или отправлять вопросы с сайта по адресу: http://rusfaq.ru/cgi-bin/Message.cgi.

(C) 2002-2003 Команда RusFAQ.ru.

 Персональные данные

Ваше имя:

Ваш e-mail:

Опубликовать мой e-mail в рассылке


 Вопрос и дополнение

Ваш вопрос:


Приложение (если необходимо):


Получить ответов:


 Выбор рассылки

Программисту
Assembler (40)
C / C++ (30)
Perl (4)
Builder / Delphi (16)
Pascal (31)
Basic / VBA (12)
Java / JavaScript (11)
PHP (5)
MySQL / MSSQL (4)
Пользователю
Windows 95/98/Me (42)
Windows NT/2000/XP (30)
"Железо" (29)
Поиск информации (14)
Администратору
Windows NT/2000/XP (19)
Linux / Unix (10)
Юристу
Гражданское право (7)
Семейное право (4)
Трудовое право (5)
КоАП (4)

Отправить вопрос всем экспертам выбранной рассылки.




Задать вопрос | Регистрация эксперта | Поиск в базе | Чат | Форумы | Новости
Проект экспертов RusFAQ.ru | Фотоальбом | Virus.RusFAQ.ru | Администрирование


Яндекс цитирования
© 2003 Россия, Москва. Авторское право: RusFAQ.ru

http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное