Jak używać EOF do uruchamiania pliku tekstowego w C?

Mam plik tekstowy, który ma ciągi znaków w każdej linii. Chcę zwiększyć liczbę dla każdej linii w pliku tekstowym, ale kiedy dotrze do końca pliku, to oczywiście musi się zatrzymać. Próbowałem przeprowadzić pewne badania na temat EOF, ale nie mogłem zrozumieć, jak prawidłowo go używać.

Zakładam, że potrzebuję pętli while, ale nie wiem, jak to zrobić.

 26

3 answers

Sposób wykrycia EOF zależy od tego, czego używasz do odczytu strumienia:

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

Sprawdź wynik wywołania wejściowego pod kątem odpowiedniego warunku powyżej, a następnie wywołaj feof(), aby określić, czy wynik był spowodowany uderzeniem EOF lub innym błędem.

Używając 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
 }

Używając 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
}

Używając fgetc():

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

Używając 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
}

Zauważ, że formularz jest taki sam dla wszystkich: sprawdź wynik operacji read; jeśli nie powiodło się, następnie sprawdź EOF. Zobaczysz wiele przykładów takich jak:

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

Ten formularz nie działa tak, jak ludzie myślą, ponieważ feof() nie zwróci true dopóki po próbie odczytania końca pliku. W rezultacie pętla wykonuje o jeden raz za dużo, co może, ale nie musi, spowodować smutek.

 72
Author: John Bode,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-02 22:55:01

Jedna możliwa pętla C to:

#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.
        */
    }
}

Na razie zignorowałbym feof i podobne funkcje. Exprience pokazuje, że zbyt łatwo jest nazwać to w niewłaściwym czasie i przetworzyć coś dwa razy w przekonaniu, że eof nie został jeszcze osiągnięty.

Pułapka, której należy unikać: użycie {[2] } dla Typu c. getchar zwraca następny rzucony znak na unsigned char, a następnie na int. Oznacza to, że na większości platform [sane] wartości EOF i ważnych wartości "char" w c nie nakładają się na siebie więc nigdy przypadkowo nie wykryje EOF dla "normalnego" char.

 11
Author: CB Bailey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-02 21:51:57

Powinieneś sprawdzić EOF po wczytaniu z pliku.

fscanf_s                   // read from file
while(condition)           // check EOF
{
   fscanf_s               // read from file
}
 0
Author: Nematollah Zarmehi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-05 12:18:02