fgetc (): Достаточно ли просто проверить EOF? - PullRequest
8 голосов
/ 27 ноября 2010

В различных примерах, найденных в Интернете, fgetc() используется следующим образом:

FILE *fp = fopen(PATH, "r");

if (fp == NULL) {
    perror("main");
    exit(EXIT_FAILURE);
}

int ch;

while (ch = fgetc(fp) != EOF) {
    // do something
}

Но в соответствии с man-страницей fgetc ()

Если происходит ошибка чтениядолжен быть установлен индикатор ошибки для потока, fgetc () должен возвратить EOF, [CX] и установить errno для индикации ошибки.

Так нужно ли это проверять?И как?

Ответы [ 3 ]

7 голосов
/ 27 ноября 2010

Вы можете проверить это с помощью ferror (3), сразу после того, как время:

while (EOF != (ch = fgetc(fp)))
   // do something

if (ferror(fp) != 0)
   // error handling

ferror возвращает ненулевое значение, если произошла ошибка.

Если вы хотите использовать fp послепроизошла ошибка, вам нужно сбросить флаг ошибки с помощью clearerr:

clearerr(fp);
6 голосов
/ 27 ноября 2010

Вот что говорят спецификации:

функция fgetc () должна получить следующий байт в виде знака без знака, преобразованного в int

Следующее имя макроса должно быть определено как отрицательное целочисленное константное выражение: EOF

Пока вы сохраняете возвращаемое значение в int, а не в char, достаточно проверить EOF, потому что гарантированно не будет отображаться действительное значение символа.


Также в вашем коде это:

while (ch = fgetc(fp) != EOF)

должно быть:

while ((ch = fgetc(fp)) != EOF)

Требуются дополнительные скобки, поскольку != имеет более высокий приоритет, чем =.

6 голосов
/ 27 ноября 2010

Цикл, пока fgetc не вернется EOF, прекрасно. После этого, если вы хотите узнать, закончился ли цикл из-за простого достижения конца файла или из-за ошибки, вы должны вызвать ferror или feof. Если вам все равно, вы можете пропустить звонок.

Обратите внимание, что имеет значение, проверяете ли вы feof или ferror, потому что индикатор ошибки для потока является липким и может оценить значение true, даже если нажатие eof было причиной сбоя fgetc. Обычно вы должны использовать feof для проверки, и если он возвращает false, заключите, что цикл остановлен из-за новой ошибки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...