При использовании кода
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<
Комментариев нет:
Отправить комментарий