web-dev-qa-db-fra.com

fgets pour lire ligne par ligne dans les fichiers

Je comprends que fgets lit jusqu'à EOF ou une nouvelle ligne.

J'ai écrit un exemple de code pour lire les lignes d'un fichier et j'ai observé que les fgets sont exécutés plus que le nombre souhaité de fois. Il s'agit d'un fichier très simple avec exactement deux lignes vides, c'est-à-dire. J'ai appuyé une fois sur Entrée et enregistré le fichier.

Voici le code:

fp = fopen("sample.txt","r");
while (!feof(fp)) {
        fgets(line,150,fp);
        i++;
        printf("%s",line);
}
printf("%d",i);

Pourquoi la boucle while est-elle exécutée trois fois au lieu de 2, car il n'y a que deux lignes vides dans le fichier?

8
codeara

Dans votre cas, la dernière ligne est apparemment lue deux fois, sauf qu'elle ne l'est pas. Le dernier appel à fgets renvoie NULL pour indiquer que la fin du fichier a été lue. Vous ne vérifiez pas cela et imprimez à nouveau l'ancien contenu du tampon, car le tampon n'a pas été mis à jour.

Il est généralement préférable de ne pas utiliser feof du tout et de vérifier les valeurs de retour de f... famille de fonctions:

fp = fopen("sample.txt", "r");
while (1) {
        if (fgets(line,150, fp) == NULL) break;
        i++;
        printf("%3d: %s", i, line);
}
printf("%d\n",i);

La fonction feof renvoie true après avoir tenté de lire au-delà de la fin du fichier, ce qui ne se produit qu'après votre dernier appel (infructueux) à fgets, qui essaie de lire à ou plutôt juste avant la fin du fichier. Les réponses dans ce long SO post expliquent plus.

18
M Oehm