Feof проверка признака конца файла


int feof(FILE *stream)

Макросом feof() контролируется указатель положения в файле — для того, чтобы установить, достигнут ли конец файла, связанный с потоком stream. Если указатель положения в файле нахо­дится в конце файла, то возвращается ненулевое значение; в противном случае возвращается нуль.

Если конец файла был уже достигнут, то последующие операции чтения будут возвращать EOF до одного из двух событий: вызова rewind() или смещения указателя положения в файле с помо­щью fseek().

Макрос особенно полезен при работе с двоичными файлами, поскольку маркер конца файла — также допустимое двоичное целое число. Для определения момента достижения конца файла необходимо в явной форме вызывать feof(), а не просто проверять переменную, возвращаемую, например, функцией getc().

Feof проверка признака конца файла

При работе с файлами в C++ очень важно построить код так, чтобы он мог работать с любыми файлами произвольного размера. В этом немаловажную роль играет функция feof(filestream), находящаяся в библиотеке cstdio или более старой библиотеке stdio.h.

Что же делает эта функция? Она проверяет, достигнут ли конец файла, с которым идет работа через поток данных (параметр filestream). Если внутренний указатель файла еще не достиг конца (последнего символа в файле), тогда функция возвращает ноль, в ином случае – значение, отличное от нуля. Рассмотрим пример работающей программы:

Закрытие файла

Читайте также:

  1. Adobe Premiere Pro, как контрольные точки. Эти точки могут использоваться для запуска событий в файлах
  2. Атрибуты файла
  3. Ввод из файла
  4. Ввод информации из файла
  5. Выбор файла
  6. Диалоговое окно открытия файла
  7. Диффузия Обеспечивает дизеринг высокого качества, но увеличивает размер файла и время обработки.
  8. ДОБАВЛЕНИЕ ДЕТАЛИ ИЗ ФАЙЛА
  9. Добавление к проекту существующего файла с исходным текстом
  10. Закрытие проекта
  11. Закрытие счетов отклонений в конце периода

Обработка открытого файла

Каким образом можно прочитать уже открытый файл или записать в него информацию? Для этого в языке C существуют специальные функции:

Чтение (ввод) Запись (вывод)
fgetc() fputc()
fscanf() fprintf()
fgets() fputs()
fread() fwrite()

При каждой операции ввода/вывода указатель текущей позиции файла смещается на одну позицию в сторону конца файла.

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

Так как при каждой операции ввода/вывода происходит перемещение указателя текущей позиции в файле, в какой-то момент указатель достигает конца файла. Структура типа FILE имеет поле – индикатор конца файла. Функция feof() проверяет состояние индикатора конца файла и возвращает значение 0, если конец файла не был достигнут, или значение, отличное от нуля, если был достигнут конец файла. Функция имеет единственный аргумент – указатель на FILE. Вызов функции в команде if:

проверяет, что конец файла еще не достигнут.

После завершения обработки файла его следует закрыть с помощью функции fclose(). При этом разрывается связь указателя на файл c внешним набором данных. Освободившийся указатель можно использовать для другого файла. Формат вызова функции:

При нормальном завершении программы в большинстве операционных систем все открытые файлы закрываются автоматически, но рекомендуется закрывать все файлы, дальнейшая обработка которых в программе не предполагается, при помощи функции fclose().

Функции ввода/вывода

Простейший способ выполнить чтение из файла или запись в файл – использовать функции fgetc() или fputc().

Функция getc() выбирает из файла очередной символ; ей нужно только знать указатель на файл, например,

Если при обработке достигается конец файла, то функция getc() возвращает значение EOF(end of file).

Функция putc() заносит значение символа Symb в файл, на который указывает out. Формат вызова функции:

Пример 1. Текст из файла my_char.txtвыводится на экран. Если файл не найден, на экран выводится сообщение «File not found!»:

FILE *ptr; //описание указателя на файл

unsigned char ch;

if ((ptr=fopen(«my_char.txt»,»r»))!=NULL)//открытие файла для чтения

ch=fgetc(ptr); //чтение первого символа из файла

while (!feof(ptr)) //цикл до конца файла

printf(«%c»,ch); //вывод символа, взятого из файла

ch=fgetc(ptr); //чтение следующего символа из файла

fclose(ptr); //закрытие файла

else printf(«\nFile not found!»);

В этом примере для чтения файла используется указатель ptr. При открытии файла производится проверка. Если переменной ptr присвоено значение NULL, то файл не найден; на экран выводится соответствующее сообщение, и программа завершается. Если ptr получил ненулевое значение, то файл открыт. Далее выполняется чтение символов из файла до тех пор, пока не будет достигнут конец файла (!feof(ptr)). Прочитанный символ помещается в переменную ch, а затем выводится на экран.

Пример 2. Записать в файл буквы, вводимые с клавиатуры. Ввод продолжается до нажатия клавиши F6 или CTRL/z (ввод символа EOF – конца файла):

FILE *out; // описание указателя на файл

out=fopen(«Liter.txt»,»w»); //открытие файла для записи

while ( (c=getchar( ))!=EOF) /*пока не будет введен символ конца

fputc(c,out); // запись введенного символа в файл

fclose(out); //закрытие файла

Функции fscanf() и fprintf() выполняют форматированный ввод/вывод.

Чтение из файла выполняет функция fscanf():

fscanf(fin,[«строка формата«],[список адресов переменных]);

Функция возвращает количество введенных из файла значений или EOF.

Запись в файл осуществляет функция fprintf():

fprintf(out,[«строка формата«],[список переменных, констант]);

Возвращает количество выведенных в файл байт (символов) или EOF.

Строка формата функций fscanf() и fprintf() формируется так же, как было описано ранее в главе, посвященной консольному вводу/выводу и функциям printf() и scanf().

Следует заметить, что вызов функции

fscanf(stdin,[строка формата],[список адресов переменных]);

scanf([строка формата],[список адресов переменных]);

fprintf(stdout, [строка формата],[список переменных, констант]);

printf([строка формата],[список переменных, констант]);

Рассмотрим примеры программ, использующих эти функции.

Пример 3. В программе создается массив, состоящий из четырех целых чисел. Вывести массив в файл:

int array[n]=<4,44,446,4466>; //описание и инициализация масcива

FILE *out; //описание указателя на файл

out=fopen(«num_arr.txt»,»w»); //открытие файла для записи

Дата добавления: 2014-12-26 ; Просмотров: 222 ; Нарушение авторских прав? ;

Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет

Признак конца файла

Дата добавления: 2013-12-23 ; просмотров: 1265 ; Нарушение авторских прав

При достижении конца файла программа должна остановиться по достижении конца файла. Если при попытке чтения символа функция getc()встречает символ конца файла, возвращается специальное значение EOF. Программа на С обнаруживает конец файла после того, как пытается считать символ, находящийся за признаком конца файла.

ch=getc(fp); //получение начального ввода

putchar(); // обработка ввода

cp=getc(fp); // получение следующего ввода

Функция fclose() закрывает файл, при этом очищаются буферы. Желательно проверить – был ли файл успешно закрыт. Функция fclose() возвращает 0 при успешном закрытии файла или EOF – в других случаях.

Илон Маск рекомендует:  Что такое код pcntl_fork

if (fclose(fp)!=0) printf(“Ошибка при закрытии файла\n”);

Функции fprintf(), fscanf(), fgets(), fputs()

Функции ввода/вывода файлов, fprintf()иfscanf()функционируют точно так же, как printf()иscanf().Разница заключается в применении дополнительного первого аргумента, определяющего файл.

Функция fgets() имеет три аргумента: первый аргумент – это адрес, по которому необходимо сохранить результаты ввода; второй аргумент – целое число, представляющее собой максимальный размер вводимой строки; третий аргумент – файловый указатель, идентифицирующий считываемый файл.

fgets(buf, MAX, fp);

Здесьbuf– имя массива типаchar,MAX – максимальный размер строки, а fp — указатель на FILE.

Функция fgets() считывает информацию из входного потока до тех пор, пока не встретит первый символ новой строки или же пока считано менее, чем задано верхним пределом количества символов минус один или же пока не достигнут конец файла. Затем функция fgets()добавляет конечный нулевой символ с целью формирования строки. Если fgets()считывает целую строку до того, как достигнут предел, в конце строки добавляется символ новой строки, как раз перед нулевым символом. В этом она отличается от функции gets(), которая считывает символ новой строки, но опускает его. Как и gets(),функция возвращает значение NULLв случае, если встречается символ EOF.

Функцияfputs()имеет два аргумента: адрес строки и файловый указатель. Она записывает строку, найденную по указателю, в файл. В отличие от puts()она не добавляет символ новой строки при выводе.


Произвольный доступ к файлам: функции fseek()иftell()

Функция fseek() позволяет обращаться с файлом как с массивом и перемещаться напрямую к любому нужному байту в файле, открытом с помощью функции fopen().Первый из трех аргументов функции fseek() –это указатель наFILE.Второй аргумент называется смещением, с его помощью функция получает информацию о том, как далеко следует продвинуться от начальной точки. Тип аргумента должен соответствовать long. Он может быть положительным (движение вперед), отрицательным (движение назад) или нулевым (оставаться на месте). Третий аргумент – режим выбора начальной точки:

Обработка открытого файла

Каким образом можно прочитать уже открытый файл или записать в него информацию? Для этого в языке C существуют специальные функции:

Чтение (ввод) Запись (вывод)
fgetc() fputc()
fscanf() fprintf()
fgets() fputs()
fread() fwrite()

При каждой операции ввода/вывода указатель текущей позиции файла смещается на одну позицию в сторону конца файла.

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

Так как при каждой операции ввода/вывода происходит перемещение указателя текущей позиции в файле, в какой-то момент указатель достигает конца файла. Структура типа FILE имеет поле – индикатор конца файла. Функция feof() проверяет состояние индикатора конца файла и возвращает значение 0, если конец файла не был достигнут, или значение, отличное от нуля, если был достигнут конец файла. Функция имеет единственный аргумент – указатель на FILE. Вызов функции в команде if:

проверяет, что конец файла еще не достигнут.

Функции ввода/вывода

Простейший способ выполнить чтение из файла или запись в файл – использовать функции fgetc() или fputc().

Функция fgetc() выбирает из файла очередной символ; ей нужно только знать указатель на файл, например:

Если при обработке достигается конец файла, то функция fgetc() возвращает значение EOF(end of file).

Функция fputc() заносит значение символа Symb в файл, на который указывает указатель out. Формат вызова функции:

Пример 1. Текст из файла my_char.txtвыводится на экран. Если файл не найден, на экран выводится сообщение «File not found!»:

FILE *ptr; //описание указателя на файл

if ((ptr=fopen(«my_char.txt«,«r«))!=NULL)/*открытие файла для чтения*/

ch=fgetc(ptr); //чтение первого символа из файла

while (!feof(ptr)) //цикл пока не достигнут конец файла

printf(«%c»,ch); //вывод символа, взятого из файла

ch=fgetc(ptr); //чтение следующего символа из файла

fclose(ptr); //закрытие файла

else printf(«\nFile not found!»);

В этом примере для чтения файла используется указатель ptr. При открытии файла производится проверка. Если переменной ptr присвоено значение NULL, то файл не найден; на экран выводится соответствующее сообщение, и программа завершается. Если ptr получил ненулевое значение, то файл открыт. Далее выполняется чтение символов из файла до тех пор, пока не будет достигнут конец файла (!feof(ptr)). Прочитанный символ помещается в переменную ch, а затем выводится на экран.

Пример 2. Записать в файл буквы, вводимые с клавиатуры. Ввод продолжается до нажатия клавиши F6 или CTRL/z (ввод символа EOF – конца файла):

FILE *out; // описание указателя на файл

out=fopen(«Liter.txt«,«w«); //открытие файла для записи

while ( (c=getchar( ))!=EOF) /*пока не будет введен символ конца */

fputc(c,out); // запись введенного символа в файл

fclose(out); //закрытие файла

Функция fgets() читает строку символов из файла. Она отличается от функции gets() тем, что в качестве второго параметра должно быть указано максимальное число вводимых символов плюс единица, а в качестве третьего — указатель на переменную файлового типа. Строка считывается целиком, если ее длина не превышает указанного числа символов, в противном случае функция возвращает только заданное число символов.

fgets(string, n, fp);

Функция возвращает указатель на строку string при успешном завершении и константу NULL в случае ошибки либо достижения конца файла.

Функция fputs() записывает строку символов в файл. Она отличается от функции puts() тем, что в качестве второго параметра должен быть записан указатель на переменную файлового типа.

При возникновении ошибки возвращается значение EOF.

Пример 3. Имеется текстовый файл. Определить длины строк этого файла:

int _tmain(int argc, _TCHAR* argv[])

FILE *fo;

fo = fopen(«prim.txt«,«r«); //открытие файла для чтения

while (!feof(fo))//цикл пока не конец файла

fgets(st,125,fo); //читать строку символов

if (!feof(fo)) //если не конец файла

Feof проверка признака конца файла

feof — Проверяет, достигнут ли конец файла

Описание

Функция возвращает TRUE в случае, когда дескриптор указывает на достижение конца файла или же если произошла ошибка (включая таймаут сокета), иначе возвращает FALSE.

Если подключение, открытое при помощи fsockopen() не было закрыто сервером, feof() будет ждать достижения таймаута прежде чем вернуть TRUE. Время таймаута по умолчанию равно 60 секундам. Вы можете использовать stream_set_timeout() для того, чтобы изменить это значение.

Указатель на файл должен быть корректным и указывать на файл, успешно открытый функциями fopen() или fsockopen() (и все еще не закрытым функцией fclose() ).

Как feof() действительно знает, когда достигнут конец файла?

Я новичок в С++ и стараюсь лучше понять feof() . Я читал, что флаг feof() установлен в true только после того, как вы пытаетесь прочитать за концом файла столько раз, когда новички будут читать еще раз, чем ожидали, если они сделают что-то вроде while(!feof(file)) . То, что я пытаюсь понять, так это то, как он на самом деле интерпретирует, что была сделана попытка прочесть конец файла? Уже прочитан весь файл и количество уже известных символов или есть какой-то другой механизм на работе?

Илон Маск рекомендует:  Кнопка button

Я понимаю, что это может быть дублирующий вопрос где-то, но я не смог его найти, вероятно, потому, что я не знаю, как лучше всего говорить о том, что я прошу. Если уже есть ответ, ссылка будет очень оценена. Благодарю.

Независимо от того, что делает библиотека С++, в конце концов она должна читать из файла. Где-то в операционной системе есть фрагмент кода, который в конечном итоге обрабатывает это чтение. Он получает из файловой системы длину файла, сохраняя то же самое, что файловая система хранит все остальное. Зная длину файла, позицию чтения и количество прочитанных байтов, он может определить, что чтение низкого уровня попадает в конец файла.

Когда это определение сделано, оно передается в стек. В конце концов, он попадает в стандартную библиотеку, которая внутренне записывает, что конец файла был достигнут. Когда запрос чтения в библиотеку пытается пройти мимо этого записанного конца, установлен флаг EOF и feof начнет возвращать true.

feof() является частью стандартного буферизованного ввода-вывода C-библиотеки. Поскольку он буферизирован, fread() предварительно считывает некоторые данные (определенно, не весь файл). Если во время буферизации fread() обнаруживает EOF (базовая процедура ОС возвращает специальное значение, обычно -1 ), она устанавливает флаг в структуре FILE . feof() просто проверяет этот флаг. Таким образом, feof() возврат истины по существу означает «предыдущая попытка чтения, обнаруженная в конце файла».

Как обнаруживается EOF, зависит от ОС /FS и не имеет ничего общего с библиотекой/языком C. У ОС есть некоторый интерфейс для чтения данных из файлов. Библиотека C — это просто мост между ОС и программой, поэтому вам не нужно менять свою программу, если вы перейдете на другую ОС. ОС знает, как файлы хранятся в своей файловой системе, поэтому он знает, как обнаружить EOF. Я предполагаю, что обычно это выполняется путем сравнения текущей позиции с длиной файла, но это может быть не так просто и может включать в себя множество деталей низкого уровня (например, что, если файл находится на сетевом диске?).

Интересным вопросом является то, что происходит, когда поток находится в конце, но он еще не был обнаружен при чтении. Например, если вы открываете пустой файл. Первый вызов feof() перед тем, как какой-либо fread() возвращает true или false? Ответ, вероятно, неверный. Документы не очень понятны по этому вопросу:

Этот индикатор обычно устанавливается предыдущей операцией в потоке которые пытались прочитать в конце файла или за ним.

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

c — feof обнаружения ложного конца файла

Я задал другой вопрос об этом раньше, но я был в стороне от проблемы, поэтому я создал новый вопрос, поскольку задаю совершенно другой вопрос.

У меня есть функция, которая читает данную строку в текстовом файле (задается переменной переменного тока). Он выполняет чтение строки, а затем проверяет, была ли последняя строка в файле. Если это так, он увеличивает значение.

Проблема в том, что она увеличивала значение, даже если это не фактический конец файла. Я думаю, что ошибаюсь, но мне не удавалось заставить его работать:

Образец данных по запросу, это текстовый файл, который я могу использовать:

fscanf правильно присваивает значения. Во второй строке feof возвращает true и завершается, увеличивается. feof возвращает true снова для третьей строки, а приращения завершаются второй раз.

    2 2
  • 17 май 2020 2020-05-17 03:12:55
  • Dawson

2 ответа

Трудно сказать, не зная формат данных, но

будет читать 3 значения, но в последней строке он не будет читать символ конца строки, поэтому это не конец файла.

  • 17 май 2020 2020-05-17 03:12:57
  • parkydr

feof() не определяет, закончился ли файл. Он обнаруживает, что последняя ошибка чтения была связана с завершением файла.

feof() происходит только после неудачного чтения.

Итак, сначала прочитайте данные и проверьте возвращаемое значение. Если при чтении не удалось использовать feof() чтобы убедиться, что она не сработала, потому что был достигнут КОНЕЦ-ФАЙЛ (другие причины для отказа чтения — это некоторая ошибка (сеть вниз, плохой сектор, принтер горит. ), обнаруживаемый с помощью ferror() ).

Обработка открытого файла

Каким образом можно прочитать уже открытый файл или записать в него информацию? Для этого в языке C существуют специальные функции:

Чтение (ввод) Запись (вывод)
fgetc() fputc()
fscanf() fprintf()
fgets() fputs()
fread() fwrite()

При каждой операции ввода/вывода указатель текущей позиции файла смещается на одну позицию в сторону конца файла.

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

Так как при каждой операции ввода/вывода происходит перемещение указателя текущей позиции в файле, в какой-то момент указатель достигает конца файла. Структура типа FILE имеет поле – индикатор конца файла. Функция feof() проверяет состояние индикатора конца файла и возвращает значение 0, если конец файла не был достигнут, или значение, отличное от нуля, если был достигнут конец файла. Функция имеет единственный аргумент – указатель на FILE. Вызов функции в команде if:

проверяет, что конец файла еще не достигнут.

Закрытие файла

После завершения обработки файла его следует закрыть с помощью функции fclose(). При этом разрывается связь указателя на файл c внешним набором данных. Освободившийся указатель можно использовать для другого файла. Формат вызова функции:

При нормальном завершении программы в большинстве операционных систем все открытые файлы закрываются автоматически, но рекомендуется закрывать все файлы, дальнейшая обработка которых в программе не предполагается, при помощи функции fclose().

Не нашли то, что искали? Воспользуйтесь поиском:

Лучшие изречения: На стипендию можно купить что-нибудь, но не больше. 8987 — | 7235 — или читать все.

188.64.174.135 © studopedia.ru Не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования. Есть нарушение авторского права? Напишите нам | Обратная связь.

Отключите adBlock!
и обновите страницу (F5)

очень нужно

Feof проверка признака конца файла

(PHP 4, PHP 5, PHP 7)

feof — Проверяет, достигнут ли конец файла

Описание

Проверяет, достигнут ли конец файла.

Список параметров

Указатель на файл должен быть корректным и указывать на файл, успешно открытый функциями fopen() или fsockopen() (и все еще не закрытый функцией fclose() ).

Возвращаемые значения

Возвращает TRUE , если указатель файла указывает на EOF или произошла ошибка (в том числе тайм-аут сокета), иначе возвращает FALSE .

Примечания

Если подключение, открытое при помощи fsockopen() , не было закрыто сервером, feof() повиснет. Для варианта обхода этого поведения смотрите следующий пример:

Пример #1 Обработка тайм-аутов с функцией feof()

return feof ( $fp );
>

/* Предположим, что $fp был ранее открыт с помощью fsockopen() */

$start = NULL ;
$timeout = ini_get ( ‘default_socket_timeout’ );

while(! safe_feof ( $fp , $start ) && ( microtime ( true ) — $start ) $timeout )
<
/* Обработка */
>
?>

Если передан неверный файловый указатель, то вы можете получить бесконечный цикл, так как feof() не сможет вернуть TRUE .

Пример #2 Пример feof() с неверным файловым указателем

// если файл не может быть прочтен или не существует, fopen вернет FALSE
$file = @ fopen ( «no_such_file» , «r» );

// FALSE от fopen вызовет предупреждение и следующий цикл станет бесконечным
while (! feof ( $file )) <
>

User Contributed Notes 16 notes

I really thought that the feof() was TRUE when the logical file pointer is a EOF.
but no !
we need to read and get an empty record before the eof() reports TRUE.

$fp = fopen(‘test.bin’,’rb’);
while(!feof($fp)) <
$c = fgetc($fp);
// . do something with $c
echo ftell($fp), «,»;
>
echo ‘EOF!’;

prints for two time the last byte position.
If our file length is 5 byte this code prints

Because of this, you have to do another check to verify if fgetc really reads another byte (to prevent error on «do something with $c» ^_^).

To prevent errors you have to use this code

$fp = fopen(‘test.bin’,’rb’);
while(!feof($fp)) <
$c = fgetc($fp);
if($c === false) break;
// . do something with $c
>

but this is the same of

$fp = fopen(‘test.bin’,’rb’);
while(($c = fgetc($fp))!==false) <
// . do something with $c
>

Consequently feof() is simply useless.
Before write this note I want to submit this as a php bug but one php developer sa >
If this is not a bug I think that this need at least to be noticed.

Sorry for my bad english.
Bye ;)

To avoid infinite loops and the warning :
«Warning: feof() expects parameter 1 to be resource, boolean given»

You need to check that the fopen function return the correct type.
This can be achieved very easily with gettype().
Here is an example :

$source = fopen($xml_uri, «r»);
$xml = «»;

if(gettype($source) == «resource») < // Check here !
while (!feof($source)) <
$xml .= fgets($source, 4096);
>
>

Here’s solution 3:

AFAICS fgets() never returns an empty string, so we can also write:

When using feof() on a TCP stream, i found the following to work (after many hours of frustration and anger):

NOTE: I used «;» to denote the end of data transmission. This can be modified to whatever the server’s end of file or in this case, end of output character is.

while( strcmp ( $cursor , «;» ) != 0 ) <
$cursor = fgetc ( $sock );
$inData .= $cursor ;
>
fclose ( $sock );
echo( $inData );
?>

Since strcmp() returns 0 when the two strings are equal, it will return non zero as long as the cursor is not «;». Using the above method will add «;» to the string, but the fix for this is simple.

$cursor = fgetc ( $sock );
while( strcmp ( $cursor , «;» ) != 0 ) <
$inData .= $cursor ;
>
fclose ( $sock );
echo( $inData );
?>

I hope this helps someone.

you can avoid the infinite loop and filling the error logs
by an simple if statement
Here is the example

Please note that feof() used with TCP-Connections, returns false as long as the connection is open.
It even returns false when there is no data available.

BTW: Using feof() with HTTP for a single request, you should always make sure that you set the HTTP-Header «Connection» to «close» and _not_ to «keep-alive».

Johannes: Remember note from stream_get_meta_data page: For socket streams this member [eof] can be TRUE even when unread_bytes is non-zero. To determine if there is more data to be read, use feof() instead of reading this item.

Another thing: better not rely on the «including socket timeout» part of when feof returns true. Just found program looping two days in while(!feof($fd)) fread . with 20 seconds timeout in PHP 4.3.10.

feof() is, in fact, reliable. However, you have to use it carefully in conjunction with fgets(). A common (but incorrect) approach is to try something like this:

The problem when processing plain text files is that feof() will not return true after getting the last line of input. You need to try to get input _and fail_ before feof() returns true. You can think of the loop above working like this:

* (merrily looping, getting lines and processing them)
* fgets used to get 2nd to last line
* line is processed
* loop back up — feof returns false, so do the steps inside the loop
* fgets used to get last line
* line is processed
* loop back up — since the last call to fgets worked (you got the last line), feof still returns false, so you do the steps inside the loop again
* fgets used to try to get another line (but there’s nothing there!)
* your code doesn’t realize this, and tries to process this non-existent line (typically by doing the same actions again)
* now when your code loops back up, feof returns true, and your loop ends

There’s two ways to solve this:

1. You can put an additional test for feof() inside the loop
2. You can move around your calls to fgets() so that the testing of feof() happens in a better location

Here’s solution 1:

And here’s solution 2 (IMHO, more elegant):

FYI, the eof() function in C++ works the exact same way, so this isn’t just some weird PHP thing.

Return values in the documentation are incorrectly stated. It says:

Returns TRUE if the file pointer is at EOF or an error occurs (including socket timeout); otherwise returns FALSE.

Correct text would be more like:

Returns FALSE if no filehandle was passed;
returns NULL if no filehandle was passed;
returns TRUE if the file pointer is at EOF or an error occurs (including socket timeout);
otherwise returns FALSE.

As an example, running the following from the commandline:

php -r ‘echo
«Empty: «.var_export(feof(), true).»\n».
«Null: «.var_export(feof(NULL), true).»\n».
«Undefined: «.var_export(feof($undef), true).»\n»
;’

This will output:

PHP Warning: Wrong parameter count for feof() in Command line code on line 1
PHP Warning: feof(): supplied argument is not a valid stream resource in Command line code on line 1
PHP Warning: feof(): supplied argument is not a valid stream resource in Command line code on line 1

Empty: NULL
Null: false
Undefined: false

This can, as other commenters have reported, result in infinite loops and massive PHP error logfiles, if the file handle returned by fopen() is invalid for any reason.

Илон Маск рекомендует:  Что такое код setvect
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL