Полагаю, вполне возможно, что :: feof () "буферизован" (поэтому он работает
правильно) while :: _ eof () "небуферизован" и считает весь файл
уже "читается" (потому что весь файл мог бы вписаться в
первый блок считывается с диска). Однако это не может быть правдой
учитывая назначение этих функций. Итак, я действительно в растерянности.
Я не знаю, почему вы думаете, что это "не может быть правдой, учитывая назначение этих функций". Эти 2 функции предназначены для работы с файлами, которые открываются и обрабатываются по-разному, поэтому они несовместимы.
На самом деле, именно это и происходит. Попробуйте это:
FILE* my_file;
// ...open "my_file" for reading...
int c;
while(0 == ::_eof(::fileno(my_file)))
{ // We are not at EOF
c = ::getc(my_file);
long offset1 = ftell(my_file);
long offset2 = _tell(fileno(my_file));
if (offset1 != offset2)
{
//here you will see that the file pointers are different
//which means that _eof and feof will fire true under different conditions
}
// ...process "c"
}
Я постараюсь уточнить немного на основе вашего комментария.
Когда вы вызываете fopen, вы получаете указатель на файл stream . Базовый объект потока хранит свой собственный указатель файла, который отделен от фактического указателя файла, связанного с базовым файловым дескриптором.
Когда вы звоните _eof, вы спрашиваете, достигли ли вы конца текущего файла. Когда вы вызываете feof, вы спрашиваете, достигли ли вы конца файла stream . Поскольку потоки файлов обычно буферизуются, конец файла достигается до конца потока.
Я все еще пытаюсь понять ваш ответ ниже, и какова цель
для _eof (), если он всегда возвращает 1, даже если вы не читали
что угодно (после первого символа).
Чтобы ответить на этот вопрос, цель _eof состоит в том, чтобы определить, достигли ли вы конца файла при использовании _open и _read для работы непосредственно с файловыми дескрипторами, а не когда вы используете fopen и fread или getc для работы с файловыми потоками. .