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

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


РАССЫЛКИ ПОРТАЛА RUSFAQ.RU

/ КОМПЬЮТЕРЫ И ПО / Языки программирования / C/C++

Выпуск № 844
от 09.09.2007, 19:05

Администратор:Калашников О.А.
В рассылке:Подписчиков: 501, Экспертов: 70
В номере:Вопросов: 1, Ответов: 4


Вопрос № 100831: Пишу тестирующую программу на BCB5. Нужно чтоб вопросы теста располагались в разных файлах. Каждый файл с вопросом - отдельный раздел. Необходимо организовать переход между файлами. Делаю так: 1. Все файлы с вопросами загоняю в массив <br...

Вопрос № 100.831
Пишу тестирующую программу на BCB5.
Нужно чтоб вопросы теста располагались в разных файлах. Каждый файл с вопросом - отдельный раздел. Необходимо организовать переход между файлами. Делаю так:
1. Все файлы с вопросами загоняю в массив

AnsiString *files;
files = new AnsiString[3];
files[0] = "question_1.txt";
files[1] = "question_2.txt";
files[2] = "question_3.txt";

2. Далее для вывода вопросов из файла исползую такую конструкцию:

for(int l=0; l<sizeof(files); l++)
{

if ((file_question = fopen(files[l].c_str(), "r")) == NULL)
{
// вывод сообщения об ошибке
}
else
{
// вывод содержимого файла на экран
}
}

Программа отказывается работать. Что делать, в чем ошибка??? Мне кажется вторая конструкция организована неверно, но в чем ошибка разобрать не могу.

Буду очень признательна за ответ!
Отправлен: 04.09.2007, 19:02
Вопрос задала: Stacey_campbell (статус: Посетитель)
Всего ответов: 4
Мини-форум вопроса >>> (сообщений: 1)

Отвечает: Maxim V.G.
Здравствуйте, Stacey_campbell!
Ваша программа отказывается работать так, как цикл организован неверно (for(int l=0; l<sizeof(files); l++)). Дело в том, что функция sizeof возвращает размер переменной находящейся в памяти. В Вашем случае размер sizeof(files) будет превышать количество строк с именами файлов. При 4 вызове в функцию fopen(files[l].c_str(), "r")) вместо имени файла попадёт мусор и соответственно программа "вылеит" (Acess vilotation .... read from adress ...). Используйте явное определение окончания цикла:
for(int l=0; l<3; l++)
{
if ((file_question = fopen(files[l].c_str(), "r")) == NULL)
{
cout << "Error" << endl;
}
else
{
cout << "File is open" << endl;
}
}

А если количество файлов неизвестно, то я бы предпочёл складывать все файлы с вопросами в отдельную папку,а потом перебирать все файлы средствами WinApi.

---------
Жить вредно - от неё умирают
Ответ отправил: Maxim V.G. (статус: 4-ый класс)
Ответ отправлен: 05.09.2007, 01:42

Отвечает: Терсков Сергей
Здравствуйте, Stacey_campbell!
Ошибка - это заголовок цикла:

for(int l=0; l
sizeof(files) вернет вам размер указателя files (т.е. 4 (дял 32-х битных систем)). Поэтому для массива лучше завести переменную размера, например size.

int size = 3;
files = new AnsiString[size];

...

delete[] files; // про очистку памяти забывать совсем не стоит...

А еще лучше воспользоваться классами библиотеки STL. Подробнее в приложении

Приложение:

Ответ отправил: Терсков Сергей (статус: Студент)
Ответ отправлен: 05.09.2007, 03:19

Отвечает: Aristos
Здравствуйте, Stacey_campbell!

Выржение sizeof(files) даст вам не количество элементов массива, а размер указателя (AnsiString*). Так происходит потому, что выражения sizeof() вычисляются во время компиляции программы. В вашем примере память под массив выделяется динамически (с помощью оператора new), то есть во время выполнения программы.
Оператор sizeof определяет количество байт выделяемых под переменную. И его можно использовать, например, следующим образом:

AnsiString files[3];
int size = sizeof(files)/sizeof(AnsiSrting); // или sizeof(files)/sizeof(files[0]);

Здесь размер массива известен при компиляции. Кроме того, для нахождения количества элементов следует разделить размер памяти, выделенной под массив, на размер памяти, занимаемый одним элементом массива, или просто размер его типа.
Ответ отправил: Aristos (статус: 5-ый класс)
Ответ отправлен: 05.09.2007, 12:02

Отвечает: Rockie
Здравствуйте, Stacey_campbell!

Количество элементов массива можно узнать, проделив размер всего массива на размер одной ячейки массива:

int len = sizeof(files/sizeof(files[0]));

Но этот способ работает при статическом выделении памяти. В данном случае вы во-первых используете string, а переменные типа string могут быть разного размера. Во-вторых если вы динамически(используя new) выделяете память под массив, вам нужно хранить его размер в отдельной переменной, так как при динамическом выделении памяти массив может располагаться в памяти по-разному и универсального способа получить его размер не существует. Код в приложении, вместо AnsiString я использовал стандартный string.

Приложение:

Ответ отправил: Rockie (статус: 3-ий класс)
Ответ отправлен: 05.09.2007, 18:46


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

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

* Код программы, выдержки из закона и т.п. дополнение к вопросу.
Эта информация будет отображена в аналогичном окне как есть.

Обратите внимание!
Вопрос будет отправлен всем экспертам данной рассылки!

Для того, чтобы отправить вопрос выбранным экспертам этой рассылки или
экспертам другой рассылки портала RusFAQ.ru, зайдите непосредственно на RusFAQ.ru.


Форма НЕ работает в почтовых программах The BAT! и MS Outlook (кроме версии 2003+)!
Чтобы отправить вопрос, откройте это письмо в браузере или зайдите на сайт RusFAQ.ru.


© 2001-2007, Портал RusFAQ.ru, Россия, Москва.
Авторское право: ООО "Мастер-Эксперт Про"
Техподдержка портала, тел.: +7 (926) 535-23-31
Хостинг: "Московский хостер"
Поддержка: "Московский дизайнер"
Авторские права | Реклама на портале
Версия системы: 4.58 от 30.08.2007
Яндекс Rambler's Top100
RusFAQ.ru | MosHoster.ru | MosDesigner.ru | RusIRC.ru
Kalashnikoff.ru | RadioLeader.ru | RusFUCK.ru

В избранное