aeris
Гость
|
|
« : 18-12-2008 22:34 » |
|
Люди..у меня есть файл и когда данные в нем заканчиваются, считывание должно опять начинаться с начала..Как это реализовать? Borland Turbo C++ Пробовала снова input_file.close(); ifstream input_file("Menu1.txt"); но считывание опять продолжается с того же места..
|
|
|
Записан
|
|
|
|
McZim
|
|
« Ответ #1 : 18-12-2008 22:50 » |
|
1. можно с помощью позиционирования в файле. 2. можно просто закрывать, а потом снова открывать файл. 3. можно ловить EOF.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
aeris
Гость
|
|
« Ответ #2 : 18-12-2008 23:11 » |
|
2. можно просто закрывать, а потом снова открывать файл. Пробовала: input_file.close(); ifstream input_file("Menu.txt") - не выходит, может, неправильно закрываю или что?
|
|
|
Записан
|
|
|
|
sss
Специалист
Offline
|
|
« Ответ #3 : 19-12-2008 02:23 » |
|
Вот пример, только без std... HANDLE hFile = ::CreateFile(...); while ( 0 == 0) { if ( FALSE == ::ReadFile( hFile, ...)) { if ( ERROR_HANDLE_EOF == ::GetLastError()) ::SetFilePointer( hFile, 0, NULL, FILE_BEGIN); else break; } } ::CloseHandle( hFile);
|
|
« Последнее редактирование: 19-12-2008 02:25 от sss »
|
Записан
|
while (8==8)
|
|
|
Вад
|
|
« Ответ #4 : 19-12-2008 06:36 » |
|
aeris, у тебя уже была ведь тема с этой проблемой: https://forum.shelek.ru/index.php/topic,17296.0.htmlГде я тебе сказал, что конструкция input_file.close(); ifstream input_file("Menu.txt");
Будет делать совсем не то, что ты подразумеваешь. Можно ведь было и спросить, что я имел в виду Или разобраться самостоятельно. Ведь что такое ifstream input_file("Menu.txt")? Это конструирование нового файлового потока - читай, создаёшь новую переменную в локальной области видимости (у тебя это ещё и внутри блока if-а делалось - иначе, оно бы и не компилировалось вовсе в связи с повторным объявлением). Значит, старая станет временно не видна в этом блоке непосредственно под своим именем, а новая только в нём и будет жить. По выходе из блока останется только старая - та самая переменная потока, который уже вычитан до конца и счастливо закрыт. Общие рекомендации: поучить матчасть насчёт областей видимости переменных в C++. Вернуть поток в начало? Для этого нужно создавать новый поток - но не так, как делаешь ты. Нужно, в таком случае, например, создавать потоки динамически - читай, ifstream *file = new ifstream("filename"). Только удалять нужно тоже не забывать.
|
|
« Последнее редактирование: 19-12-2008 06:39 от Вад »
|
Записан
|
|
|
|
АлексейК
|
|
« Ответ #5 : 19-12-2008 11:15 » |
|
Можно создать поток один раз. А файл для него открывать перед циклом и в цикле как в примере: void __fastcall TForm1::Button1Click(TObject *Sender) { int i,j; n=StrToInt(Edit1->Text);//Считываем количество клиентов Randomize(); f=0; j=1; i=1; //////////////////////////////////////////////////////// // !!!!!!!!!!!!!!!!!!!!!Исправлено !!!!!!!!!!!!!!!!!!!!!!!!!! // вместо ifstream input_file("Menu1.txt");
ifstream input_file; input_file.open("Menu1.txt"); /////////////////////////////////////////////////////// char line[64];
while (i<=n) { if (input_file.eof()) { input_file.close(); //////////////////////////////////////////////////////// // !!!!!!!!!!!!!!!!!!!!!Исправлено !!!!!!!!!!!!!!!!!!!!!!!!!! // вместо ifstream input_file("Menu1.txt");
input_file.open("Menu1.txt"); ////////////////////////////////////////////////// }; input_file.getline(line, sizeof(line)); StringGrid1->Cells[1][j]=line;//Название input_file.getline(line, sizeof(line)); StringGrid1->Cells[2][j]=line;//Cостав
//Обслуживание клиента в ресторане vibor=Random(1795)+5;//Выбор клиентом блюд 5 сек до 1800 сек zayavka=Random(160)+20;//Официант относит заявку от 20 сек до 2 минуты
input_file.getline(line, sizeof(line)); gotovka=StrToInt(line);//Готовка из БД (+5 мин) polychenie=Random(300)+15;//Получить от 15 сек до 10 мин dostavka=Random(40)+10;//Отнести от 10 сек до 50 сек t=vibor+zayavka+gotovka+polychenie+dostavka; f=f+t; StringGrid1->Cells[3][j]=IntToStr(gotovka)+" мин"; StringGrid1->Cells[4][j]=FloatToStr(t/60)+" мин"; StringGrid1->Cells[0][j]=IntToStr(i); j++; if ((Random(3)%2)==0) { i++; }; }; }
Динамическое создание потока ifstream *file = new ifstream("filename") внутри блока проблему не решит, поскольку видим он будет внутри этого блока так же как и в случае с ifstream input_file("filename");
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #6 : 19-12-2008 11:18 » |
|
АлексейК, на что спорим? присваивать указатель только не локальной переменной в блоке if надо, естественно А вот как ты организуешь n чтений файла из одного единожды открытого файлового потока? Именно в этом затыка
|
|
|
Записан
|
|
|
|
АлексейК
|
|
« Ответ #7 : 19-12-2008 11:34 » |
|
А вы предлагаете перед каждым чтением новый поток создавать? Можно вообще open сделать один раз, а к началу возвращаться с
помощью функции file.seekg( 0, ios_base::beg );
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #8 : 19-12-2008 11:54 » |
|
АлексейК, твоя правда, seekg лучше
|
|
|
Записан
|
|
|
|
aeris
Гость
|
|
« Ответ #9 : 19-12-2008 14:12 » |
|
:shock:Ой, я извиняюсь..Мона тогда ту тему удалить? Заранее спасибо Реализовала через file.seekg( 0, ios_base::beg ): int i,j,k; float u,m; k=1; ifstream file; for (i=1; i<=(StringGrid1->RowCount-1); i++) {StringGrid1->Rows[i]->Clear();};//Очищаем StringGrid n=StrToInt(Edit1->Text);//Считываем количество клиентов Randomize();//Инифиализируем функцию Random f=0; j=1; i=1; //ifstream input_file("Menu.txt"); file.open("Menu.txt"); char line[64]; while (i<=n) { if (file.eof()) {file.seekg(0,ios_base::beg);}; file.getline(line, sizeof(line)); if (k==14) {file.seekg(0,ios_base::beg);}; StringGrid1->Cells[1][j]=line;//Название file.getline(line, sizeof(line)); StringGrid1->Cells[2][j]=line;//Cостав //Обслуживание клиента в ресторане vibor=Random(1795)+600;//Выбор клиентом блюд 5 сек до 1800 сек zayavka=Random(160)+20;//Официант относит заявку от 20 сек до 2 минуты file.getline(line, sizeof(line)); gotovka=StrToInt(line);//Готовка из БД (+5 мин) polychenie=Random(300)+15;//Получить от 15 сек до 10 мин dostavka=Random(40)+10;//Отнести от 10 сек до 50 сек t=vibor+zayavka+(gotovka*60)+polychenie+dostavka;//Общее время f=f+t; StringGrid1->Cells[3][j]=IntToStr(gotovka)+" мин"; //Выводим в StringGrid время приготовления блюда m=m+t/60; StringGrid1->Cells[4][j]=FloatToStr(m)+" мин"; //Выводим в StringGrid общее время обслуживания клиента StringGrid1->Cells[0][j]=IntToStr(i);//Выводим в StringGrid номер клиента //Номер клиента j++; if ((Random(3)%2)==0) {i++;}; k++; }; Label4->Caption=FloatToStr(f/60)+" мин"; //Общее время обслуж.клиентов Label5->Caption=IntToStr((24*60)/((f/60)/n)); //Клиентов за день u=((f/60)/n); Label7->Caption=FloatToStr(u)+" мин";
Только вот вопрос о Но почему-то у меня считывается последнее значение (, при следующем считывании значение становится равным '' (не ' '), спокойно проходит проверку,что это не конец файла и дальше прога вылетает, ибо " ''' is not a valid integer value"..Я так поняла, что во этот символ последний ('') и есть признак конца файла, так почему он проверку тогда проходит? Опять поднялся - так он его в конце и считывает..Что это за символ может быть?
|
|
|
Записан
|
|
|
|
aeris
Гость
|
|
« Ответ #10 : 19-12-2008 14:51 » |
|
В общем, все работает - я просто счетчик поставила, чтобы не доходил он до этого символа..тупо, конечно, но для этой проги больше и не надо. Большое спасибо за советы, очень пригодилось! Хотя все же мне интересно, что это за символ такой.Я файл создаю в AkelPad'e, может, это он такие неотображаемые символы ставит?
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #11 : 19-12-2008 22:14 » |
|
aeris, у тебя случайно пустой строки нет в конце файла?
|
|
|
Записан
|
|
|
|
aeris
Гость
|
|
« Ответ #12 : 20-12-2008 06:12 » |
|
В том-то и дело, что нету..
|
|
|
Записан
|
|
|
|
Dr.Yevhenius
|
|
« Ответ #13 : 22-12-2009 17:43 » |
|
Решил сюда написать... Меня интересует последовательность записи байтов у файл: 1) запись массивов - сначала записывается 0-й элемент, потом 1-й и т. д.; 2) запись двухбайтового числа 1234h - сначала записывается 34h, а потом 12h. Всё верно?
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #14 : 22-12-2009 17:46 » |
|
Inkognito, все зависит от формата файла. Есть такое полезное решение - записывать в "сетевом" - платформонезависимом - формате. См. функции стандартной библиотеки Си: ntohs, htons, ntohl, htonl. При этом записывать нужно не по байтово,а как буфер: short sh_num = 0x1234; short sh_buffer; long l_num = 0x12345678; long l_buffer;
sh_buffer = htons(sh_num); write(fd, &sh_buffer, sizeof(sh_buffer)); l_buffer = htonl(l_num); write(fd, &l_buffer, sizeof(l_buffer));
|
|
« Последнее редактирование: 22-12-2009 17:50 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Dr.Yevhenius
|
|
« Ответ #15 : 22-12-2009 17:58 » |
|
Спасибо за информацию
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #16 : 22-12-2009 18:12 » |
|
Забыл добавить: int применять не стоит - он переменчив в размере от платформы к платформе.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
|