Как использовать EOF для запуска через текстовый файл в C? - PullRequest
30 голосов
/ 03 декабря 2009

У меня есть текстовый файл со строками в каждой строке. Я хочу увеличить число для каждой строки в текстовом файле, но когда он достигает конца файла, он, очевидно, должен остановиться. Я пытался провести исследование EOF, но не мог понять, как правильно его использовать.

Я предполагаю, что мне нужен цикл while, но я не уверен, как это сделать.

Ответы [ 3 ]

79 голосов
/ 03 декабря 2009

Способ определения EOF зависит от того, что вы используете для чтения потока:

function                  result on EOF or error                    
--------                  ----------------------
fgets()                   NULL
fscanf()                  number of succesful conversions
                            less than expected
fgetc()                   EOF
fread()                   number of elements read
                            less than expected

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

Использование fgets():

 char buffer[BUFFER_SIZE];
 while (fgets(buffer, sizeof buffer, stream) != NULL)
 {
   // process buffer
 }
 if (feof(stream))
 {
   // hit end of file
 }
 else
 {
   // some other error interrupted the read
 }

Использование fscanf():

char buffer[BUFFER_SIZE];
while (fscanf(stream, "%s", buffer) == 1) // expect 1 successful conversion
{
  // process buffer
}
if (feof(stream)) 
{
  // hit end of file
}
else
{
  // some other error interrupted the read
}

Использование fgetc():

int c;
while ((c = fgetc(stream)) != EOF)
{
  // process c
}
if (feof(stream))
{
  // hit end of file
}
else
{
  // some other error interrupted the read
}

Использование fread():

char buffer[BUFFER_SIZE];
while (fread(buffer, sizeof buffer, 1, stream) == 1) // expecting 1 
                                                     // element of size
                                                     // BUFFER_SIZE
{
   // process buffer
}
if (feof(stream))
{
  // hit end of file
}
else
{
  // some other error interrupted read
}

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

while(!feof(stream))
{
  fscanf(stream, "%s", buffer);
  ...
}

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

11 голосов
/ 03 декабря 2009

Один из возможных циклов C будет:

#include <stdio.h>
int main()
{
    int c;
    while ((c = getchar()) != EOF)
    {
        /*
        ** Do something with c, such as check against '\n'
        ** and increment a line counter.
        */
    }
}

На данный момент я бы проигнорировал feof и подобные функции. Опыт показывает, что слишком просто позвонить в неподходящее время и дважды что-то обработать, полагая, что eof еще не достигнуто.

Подводный камень, которого следует избегать: используйте char для типа c. getchar возвращает следующий приведенный символ к unsigned char, а затем к int. Это означает, что на большинстве [нормальных] платформ значение EOF и действительные значения "char" в c не перекрываются, поэтому вы не сможете случайно обнаружить EOF для "нормального" char .

0 голосов
/ 05 июня 2014

Вы должны проверить EOF после чтения из файла.

fscanf_s                   // read from file
while(condition)           // check EOF
{
   fscanf_s               // read from file
}
...