Страницы

Поиск по вопросам

вторник, 26 ноября 2019 г.

Правильное использование проверки конца файла


При использовании кода

while(!feof(file))
{
    // Чтение из файла
}


в C или 

while(!file.feof())
{
    // Чтение из файла
}


в C++ получаются неприятности - лишняя считанная строка, например. Почему? Как правильно проверить, что достигнут конец файла?
    


Ответы

Ответ 1



Признак достижения конца файла выставляется только после неудачной попытки чтени за его концом. Поэтому, если в теле цикла нет проверки, успешно ли выполнено чтени из файла - последнее чтение окажется именно тем неудачным чтением, которое выставит признак достигнутого конца файла (а для вас это будет выглядеть как, например, еще раз считанная последняя строка, если она находилась в буфере для чтения). Лучше в заголовке цикла while выполнять само чтение с проверкой - например, в программе на C это могло бы выглядеть как while(fread(&data,sizeof(data),1,file)==1) { // Обработка считанных данных } if (feof(file)) // Достигнут конец файла puts("Ошибка чтения: достигнут конец файла"); else if (ferror(file)) { puts("Ошибка чтения файла"); или на C++ - наподобие for(int n; file >> n; ) { // Обработка считанного значения n } if (file.bad()) std::cout << "Ошибка ввода-вывода при чтении\n"; else if (file.eof()) std::cout << "Достигнут конец файла\n"; else if (file.fail()) std::cout << "Неверный формат данных\n";

Ответ 2



Также помимо флага eof после чтения всего файла может также выставиться флаг fail и если мы захотим установить курсор на начало fin.seekg(0, fin.beg), то ничего не прочитаем, т.к. флаг fail не сброшен. Сбросить можно с помощью fin.clear(). Текущее состояние можно вывести fin.rdstate(): ifstream fin; fin.open("E://1.txt", ios_base::in); string str; while(getline(fin, str)) { cout<< str<< " " << fin.rdstate() << endl ; } if (fin.bad()) std::cout << "bad" << endl; if (fin.eof()) std::cout << "eof" << endl; if (fin.fail()) std::cout << "bad | fail" << endl; fin.clear(); fin.seekg(0, fin.beg); if (fin.bad()) std::cout << "bad" << endl; if (fin.eof()) std::cout << "eof" << endl; if (fin.fail()) std::cout << "bad | fail" << endl; while(getline(fin, str)) { cout<

Комментариев нет:

Отправить комментарий