EOF manquant pour le fichier Unix

Duplication possible:
fgetc n’identifie pas EOF
fgetc, vérification EOF

J’ai créé un fichier et l’ai nommé “fichier.txt” dans Unix. J’ai essayé de lire le contenu du fichier de mon programme C. Je ne suis pas en mesure de recevoir le caractère EOF. Unix ne stocke pas le caractère EOF lors de la création d’un fichier? Si oui, quelle est la manière alternative de lire l’EOF à partir d’un fichier créé sous Unix à l’aide de C.

Voici l’exemple de code

int main(){ File *fp; int nl,c; nl =0; fp = fopen("file.txt", "r"); while((c = fgetc(fp)) != EOF){ if (c=='\n') nl++; } return 0; } 

Si je donne explicitement CTRL + D, l’EOF est détecté même lorsque j’utilise le caractère char c .

Cela peut arriver si le type de c est char (et que char n’est pas signé dans votre compilateur, vous pouvez le vérifier en examinant la valeur de CHAR_MIN in) et non int .

La valeur de EOF est négative selon la norme C.

Ainsi, la EOF implicite d’ EOF en caractères unsigned char perdra la valeur réelle d’ EOF et la comparaison échouera toujours.

MISE À JOUR : Il y a un plus gros problème qui doit être résolu en premier. Dans l’expression c = fgetc(fp) != EOF , fgetc(fp) != EOF est évaluée en premier (à 0 ou 1), puis la valeur est assignée à c . S’il y a au moins un caractère dans le fichier, fgetc(fp) != EOF sera évalué à 0 et le corps de la boucle while ne s’exécutera jamais. Vous devez append des parenthèses, comme ceci: (c = fgetc(fp)) != EOF .

Parenthèses manquantes. Devrait être:

 while((c = fgetc(fp)) != EOF) 

Rappelez-vous: fgetc() renvoie un int , pas un char . Il doit renvoyer un int car son ensemble de valeurs de retour inclut tous les caractères valides possibles, plus un indicateur EOF distinct (négatif).

Il y a deux pièges possibles si vous utilisez le type char pour c au lieu de int :

  1. Si le type char est signé avec votre compilateur, vous détecterez un caractère valide comme EOF. Souvent, le caractère ÿ (y-umlaut, officiellement appelé Unicode en tant que LATIN LOWER CASE Y AVEC DIAERESIS, U + 00FF, code hexadécimal 0xFF dans le jeu de codes ISO 8859-1 aka Latin 1) sera détecté comme équivalent à EOF, lorsque c’est un personnage valide.

  2. Si le type char n’est pas signé, la comparaison ne sera jamais vraie.

Les deux problèmes sont graves et les deux sont évités en utilisant le bon type:

 FILE *fp = fopen("file.txt", "r"); if (fp != 0) { int c; int nl = 0; while ((c = fgetc(fp)) != EOF) if (c == '\n') nl++; printf("Number of lines: %d\n", nl); } 

Notez que le type est FILE et non File . Notez que vous devez vérifier que le fichier a été ouvert avant d’essayer de lire via fp .


Si je donne explicitement CTRL + D, l’EOF est détecté même lorsque j’utilise le caractère char c .

Cela signifie que votre compilateur vous fournit un caractère de type signé. Cela signifie également que vous ne pourrez pas compter les lignes avec précision dans les fichiers contenant ÿ.


Contrairement à CP / M et DOS, Unix n’utilise aucun caractère pour indiquer EOF; vous atteignez EOF quand il n’y a plus de caractères à lire. Ce qui déroute beaucoup de gens est que si vous tapez une certaine combinaison de touches au terminal, les programmes détectent EOF. En réalité, le pilote du terminal reconnaît le caractère et envoie les caractères non lus au programme. S’il n’y a pas de caractères non lus, le programme obtient 0 octet renvoyé, ce qui est le même résultat que lorsque vous avez atteint la fin du fichier. Ainsi, la combinaison de caractères (souvent, mais pas toujours, Ctrl-D ) semble “envoyer EOF” au programme. Cependant, le caractère n’est pas stocké dans un fichier si vous utilisez cat >file ; de plus, si vous lisez un fichier contenant un contrôle-D, c’est un caractère parfaitement fin avec la valeur d’octet 0x04. Si un programme génère un contrôle-D et l’envoie à un programme, cela n’indique pas EOF au programme. C’est ssortingctement une propriété des terminaux Unix (tty et pty – teletype et pseudo-teletype – devices).

Vous ne montrez pas comment vous déclarez la variable c elle doit être de type int , pas char .