Как использовать feof (FILE * f)? - PullRequest
2 голосов
/ 29 ноября 2010

Мне тяжело с циклом do-while, который должен остановиться когда мы дойдем до конца файла. Вот код цикла:

do  {
    if (pcompanyRow[0] != '#' && pass == 1) {
        strtok(pcompanyRow, ":");
        pcompanyName = strcpy(pcompanyName, strtok(NULL, ""));
        pass = 2;
        fgets(pcompanyRow, 1024, f);
    }
    if (pcompanyRow[0] != '#' && pass == 2) {
        strtok(pcompanyRow, ":");
        pcompanySMSPrice = strcpy(pcompanySMSPrice, strtok(NULL , ""));
        pass = 3;
        fgets(pcompanyRow, 1024 , f);
    }
    if (pcompanyRow[0] != '#' && pass == 3) {
        strtok(pcompanyRow, ":");
        pcompanyMMSPrice = strcpy(pcompanyMMSPrice, strtok(NULL, ""));
        pass = 4;
        fgets(pcompanyRow, 1024, f);
    }
    if (pass == 4)  {
        AppendCompanyNode(pcompanyList, pcompanyName, pcompanySMSPrice, pcompanyMMSPrice);
        pass = 1;
    }
} while (!feof(f));

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

Как мне правильно написать?

Ответы [ 3 ]

8 голосов
/ 29 ноября 2010

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

Источник здесь . Также подробно объясняется проблема и способы ее устранения.

4 голосов
/ 29 ноября 2010

Я бы изменил ваш цикл и логику, чтобы использовать это:

while (fgets(pcompanyRow, 1024, f) != NULL) {

    /* do things */

}

когда fgets () пытается прочитать после конца файла, он вернет NULL и вы выйдете из цикла. Вы по-прежнему можете использовать pass и другие флаги / логику, но условия, которые вы проверяете, будут немного отличаться.

0 голосов
/ 11 октября 2018

Я предлагаю использовать оба fgets () и feof ().Последняя строка в файле может иметь \ n или может не иметь.Если вы используете только feof (), вы можете пропустить (потерянную) последнюю строку.

 for(;;)
 {char *pc;

  pc=fgets(buf,sizeof(buf),fd);

  if(!pc)
    {//it may be read error or end of file
      if(feof(fd))
        {//it is end of file, normal exit from for
         break;      
        }
       else
        {//it is i/o error 
         fclose(fd);
         return 2;
        }
    }
}//for
...