web-dev-qa-db-fra.com

Comment utiliser EOF parcourir un fichier texte en C?

J'ai un fichier texte qui a des chaînes sur chaque ligne. Je souhaite incrémenter un nombre pour chaque ligne du fichier texte, mais il doit évidemment s'arrêter lorsqu'il atteint la fin du fichier. J'ai essayé de faire des recherches sur EOF, mais je ne comprenais pas vraiment comment l'utiliser correctement.

Je suppose que j'ai besoin d'une boucle while, mais je ne sais pas comment faire.

29
Tyler Treat

La façon dont vous détectez EOF dépend de ce que vous utilisez pour lire le flux:

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

Vérifiez le résultat de l'appel d'entrée pour la condition appropriée ci-dessus, puis appelez feof() pour déterminer si le résultat est dû à une frappe sur EOF ou à une autre erreur. 

Utilisation de 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
 }

Utilisation de 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
}

Utilisation de fgetc():

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

Utilisation de 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
}

Notez que le formulaire est le même pour tous: vérifiez le résultat de l'opération de lecture; si cela échoue, alors vérifiez EOF. Vous verrez beaucoup d'exemples comme:

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

Ce formulaire ne fonctionne pas comme les gens le pensent, car feof() ne retournera pas vrai tant que après vous aurez tenté de lire après la fin du fichier. En conséquence, la boucle en exécute une fois de trop, ce qui peut causer ou non du chagrin. 

78
John Bode

Une boucle C possible serait:

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

Pour l'instant, j'ignorerais feof et des fonctions similaires. L'expérience montre qu'il est beaucoup trop facile de l'appeler au mauvais moment et de traiter quelque chose deux fois, persuadé que l'eof n'est pas encore atteint.

Piège à éviter: utiliser char pour le type de c. getchar renvoie le caractère suivant à unsigned char, puis à int. Cela signifie que sur la plupart des plates-formes [sane], les valeurs EOF et valides "char" dans c ne se chevauchent pas et vous ne détecterez donc pas accidentellement EOF pour une char "normale".

11
CB Bailey

Vous devriez vérifier le EOF après avoir lu le fichier.

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