web-dev-qa-db-fra.com

Fin de fichier (EOF) en C

Je lis actuellement le livre C Programming Language de Ritchie & Kernighan. Et je suis assez confus quant à l'utilisation de EOF dans la fonction getchar()].

Premièrement, je veux savoir pourquoi la valeur de EOF est -1 et pourquoi la valeur de getchar()!=EOF est égale à 0. Pardonnez-moi pour ma question mais je ne comprends vraiment pas J'ai vraiment essayé mais je ne peux pas.

Ensuite, j'ai essayé d'exécuter l'exemple sur le livre qui peut compter le nombre de caractères en utilisant le code ci-dessous, mais il semble que je ne sors jamais de la boucle, même si j'appuie sur Entrée, je me demande donc quand j'atteindrai l'EOF.

main(){
   long nc;
   nc = 0;
   while (getchar() != EOF)
       ++nc;
   printf("%ld\n", nc);
}

Ensuite, j'ai lu le même problème à Problème avec EOF en C . La plupart des gens nous ont dit qu'au lieu d'utiliser EOF, utilisez le terminateur\n ou le terminateur nul '\ 0 'ce qui a beaucoup de sens.

Cela signifie-t-il que l'exemple du livre sert à autre chose?

57
newbie

EOF indique "fin du fichier". Une nouvelle ligne (ce qui se passe lorsque vous appuyez sur entrée) n'est pas la fin d'un fichier, c'est la fin d'un ligne, donc une nouvelle ligne ne termine pas ce boucle.

Le code n'est pas faux [*], il ne fait tout simplement pas ce que vous semblez attendre. Il lit jusqu'à la fin de l'entrée, mais vous semblez vouloir lire uniquement jusqu'à la fin d'une ligne.

La valeur de EOF est -1 car elle doit être différente de toute valeur renvoyée de getchar qui est un caractère réel. Donc, getchar renvoie une valeur de caractère. comme un caractère non signé, converti en int, qui sera donc non négatif.

Si vous tapez sur le terminal et que vous souhaitez provoquer une fin de fichier, utilisez CTRL-D (systèmes de style unix) ou CTRL-Z (Windows). Ensuite, une fois que toutes les entrées ont été lues, getchar() renverra EOF et, par conséquent, getchar() != EOF sera faux et la boucle se terminera.

[*] Eh bien, il a un comportement indéfini si l'entrée contient plus de caractères LONG_MAX en raison d'un dépassement d'entier, mais nous pouvons probablement pardonner cela dans un exemple simple.

81
Steve Jessop

EOF est -1 parce que c'est ainsi qu'il est défini. Le nom est fourni par les en-têtes de bibliothèque standard que vous avez #include. Ils le rendent égal à -1 car il doit s'agir de quelque chose qui ne puisse être confondu avec un octet lu par getchar(). getchar() rapporte les valeurs des octets réels en utilisant un nombre positif (0 à 255 inclus), donc -1 fonctionne bien pour cela.

L'opérateur != Signifie "pas égal". 0 signifie faux et tout le reste est vrai. Nous appelons donc la fonction getchar() et comparons le résultat à -1 (EOF). Si le résultat n'était pas égal à EOF, alors le résultat est vrai, car les éléments qui ne sont pas égaux ne sont pas égaux. Si le résultat était égal à EOF, le résultat est faux, car les éléments égaux ne sont pas égaux.

L'appel à getchar() renvoie EOF lorsque vous atteignez la "fin du fichier". En ce qui concerne C, "l'entrée standard" (les données que vous donnez à votre programme en tapant dans la fenêtre de commande) est comme un fichier. Bien sûr, vous pouvez toujours taper plus, vous avez donc besoin d’une manière explicite de dire "j’ai terminé". Sur les systèmes Windows, il s’agit de control-Z. Systèmes Unix, il s’agit de control-D.

L'exemple dans le livre n'est pas "faux". Cela dépend de ce que vous voulez réellement faire. Lire jusqu'à EOF signifie que vous lisez tout, jusqu'à ce que l'utilisateur dise "J'ai terminé", puis vous ne pourrez plus lire. Lire jusqu'à ce que '\ n' signifie que vous lisez La lecture jusqu’à "\ 0" est une mauvaise idée si vous attendez que l’utilisateur tape l’entrée, car il est difficile ou impossible de produire cet octet avec un clavier à la commande Invite :)

16
Karl Knechtel

Cela fait beaucoup de questions.

  1. Pourquoi EOF vaut -1: généralement -1 dans les appels système POSIX est renvoyé en cas d'erreur, je suppose donc que l'idée est "EOF est une sorte d'erreur"

  2. toute opération booléenne (y compris! =) renvoie 1 au cas où il est VRAI, et 0 au cas où il est FAUX, donc getchar() != EOF est 0 lorsqu'il est FAUX, ce qui signifie que getchar() est retourné EOF.

  3. pour émuler EOF lors de la lecture de stdin, appuyez sur Ctrl+D

7
Drakosha