Ceci est mon code source C.
Quand je le construis dans Ubuntu, il commence à obtenir des caractères mais je ne sais pas comment terminer le programme, car il ne se termine pas par une entrée ENTERou un retour chariot.
Que signifie EOF? Comment puis-je le déclencher?
Cette source figure également dans un livre de Dennis Ritchie:
#include <stdio.h>
/* count digits, white space, others */
main ()
{
int c, i, nwhite, nother;
int ndigit[10];
nwhite = nother = 0;
for (i = 0; i < 10; ++i)
ndigit[i] = 0;
while ((c = getchar ()) != EOF)
if (c >= '0' && c <= '9')
++ndigit[c - '0'];
else if (c == ' ' || c == '\n' || c == '\t')
++nwhite;
else
++nother;
printf ("digits =");
for (i = 0; i < 10; ++i)
printf (" %d", ndigit[i]);
printf (", white space = %d, other = %d\n", nwhite, nother);
}
command-line
c
stackprogramer
la source
la source
-1
est équivalent à EOF. Il est défini/usr/include/stdio.h
comme une constante macro-1
en entrée ne fonctionne pas :)Réponses:
Tl; dr
Vous pouvez généralement "déclencher EOF" dans un programme exécuté dans un terminal avec une touche CTRL+ Djuste après le dernier rinçage d'entrée.
EOF signifie Fin de fichier.
"Déclencher EOF" dans ce cas signifie à peu près "faire savoir au programme qu'aucune entrée ne sera envoyée".
Dans ce cas, puisque
getchar()
renverra un nombre négatif si aucun caractère n'est lu, l'exécution est terminée.Mais cela ne s'applique pas seulement à votre programme spécifique, il s'applique à de nombreux outils différents.
En général, le "déclenchement EOF" peut être effectué avec une touche CTRL+ Djuste après le dernier rinçage d'entrée (c'est-à-dire en envoyant une entrée vide).
Par exemple avec
cat
:Ce qui se passe sous le capot lorsque vous appuyez sur CTRL+, Dc'est que l'entrée saisie depuis le dernier rinçage d'entrée est vidée; lorsque cela se produit pour être une entrée vide de la
read()
syscall appelée sur les rendements STDIN du programme0
,getchar()
renvoie un nombre négatif (-1
dans la bibliothèque GNU C), ce qui est à son tour interprété comme EOF 1 .1 - /programming//a/1516177/4316166
la source
TL; DR : EOF n'est pas un caractère, c'est une macro utilisée pour évaluer le retour négatif d'une fonction de lecture d'entrée. On peut utiliser Ctrl+ Dpour envoyer un
EOT
caractère qui forcera le retour de la fonction-1
Chaque programmeur doit RTFM
Reportons-nous au "CA Reference Manual", de Harbison et Steele, 4e éd. à partir de 1995, page 317:
Ce
EOF
n'est essentiellement pas un caractère, mais plutôt une valeur entière implémentéestdio.h
pour représenter-1
. Ainsi, la réponse de kos est correcte dans la mesure où cela va, mais il ne s'agit pas de recevoir une entrée "vide". Il est important de noter qu'EOF sert ici de comparaison de valeur de retourgetchar()
, pas pour signifier un caractère réel. Leman getchar
soutient que:Considérez la
while
boucle - son objectif principal est de répéter l'action si la condition entre crochets est vraie . Regarde encore:Il dit essentiellement de continuer à faire des choses si
c = getchar()
renvoie un code réussi (0
ou supérieur; c'est une chose courante d'ailleurs, essayez d'exécuter une commande réussie,echo $?
puis échouezecho $?
et voyez les nombres qu'ils renvoient). Donc, si nous obtenons avec succès le caractère et l'assing à C, le code d'état renvoyé est 0, l'échec est -1.EOF
est défini comme-1
. Par conséquent, lorsque la condition-1 == -1
se produit, les boucles s'arrêtent. Et quand cela arrivera-t-il? Quand il n'y a plus de personnage à obtenir, quandc = getchar()
échoue. Vous pourriez écrirewhile ((c = getchar ()) != -1)
et ça marcherait toujoursRevenons également au code actuel, voici un extrait de
stdio.h
Codes ASCII et EOT
Bien que le caractère EOF ne soit pas un caractère réel, cependant, il existe un caractère
EOT
(Fin de transmission), qui a une valeur décimale ASCII de 04; il est lié au raccourci Ctrl+ D(représenté également par un méta-caractère^D
). Le caractère de fin de transmission signifiait la fermeture d'un flux de données remontant à l'époque où les ordinateurs étaient utilisés pour contrôler les connexions téléphoniques, d'où le nom de «fin de transmission».Il est donc possible d'envoyer cette valeur ascii au programme comme ceci, notez
$'\04'
qui est l'EOT:Ainsi, nous pouvons dire qu'il existe, mais il n'est pas imprimable
Note latérale
Nous oublions souvent que dans le passé, les ordinateurs n'étaient pas aussi polyvalents - les concepteurs doivent utiliser toutes les touches du clavier disponibles. Ainsi, l'envoi de
EOT
caractère avec CtrlD est toujours "l'envoi d'un caractère", contrairement à la saisie de majuscules A, ShiftA, vous faites toujours donner à l'ordinateur une entrée avec les touches disponibles. Ainsi EOT est un vrai personnage dans le sens où il vient de l'utilisateur, il est lisible par ordinateur (bien que non imprimable, non visible par l'homme), il existe dans la mémoire de l'ordinateurCommentaire de Byte Commander
Oui, exactement, car
/dev/null
il n'y a pas de caractère réel à lire, donc ilc = getchar()
renverra du-1
code et le programme se fermera immédiatement. Encore une fois, la commande ne renvoie pas EOF. EOF est juste une variable constante égale à -1, que nous utilisons pour comparer le code retour de la fonction getchar .EOF
n'existe pas en tant que personnage, c'est juste une valeur statique à l'intérieurstdio.h
.Démo:
Un autre clou dans le cercueil
Parfois, on tente de prouver que EOF est un caractère avec un code comme celui-ci:
Le problème est que le type de données char peut être une valeur signée ou non signée. De plus, ce sont les plus petits types de données adressables, ce qui les rend très utiles dans les microcontrôleurs, où la mémoire est limitée. Ainsi, au lieu de déclarer,
int foo = 25;
il est courant de voir dans les microcontrôleurs à petite mémoirechar foo = 25;
ou quelque chose de similaire. De plus, les caractères peuvent être signés ou non signés .On pourrait vérifier que la taille en octets avec un programme comme celui-ci:
Quel est le but ? Le fait est que EOF est défini comme -1, mais le type de données char peut imprimer des valeurs entières .
D'ACCORD . . Et si nous essayons d'imprimer char en chaîne?
Évidemment, une erreur, mais néanmoins, l'erreur nous dira quelque chose d'intéressant:
Valeurs hexadécimales
L'impression EOF sous forme de valeur hexadécimale donne
FFFFFFFF
, une valeur de 16 bits (8 octets), compliment à deux de a-1
.Production:
Une autre chose curieuse se produit avec le code suivant:
Si l'on appuie sur Shift+ A, nous obtenons la valeur hexadécimale 41, évidemment la même que dans le tableau ASCII. Mais pour Ctrl+ D, nous avons
ffffffff
, encore une fois - la valeur de retour degetchar()
stocké dansc
.Se référer à d'autres langues
Notez que d'autres langages évitent cette confusion, car ils opèrent sur l'évaluation d'un état de sortie de fonction, et non sur la comparaison avec une macro. Comment lit-on un fichier en Java?
Et le python?
la source
/dev/null
, cela devrait également renvoyer un EOF, non? Ou qu'est-ce que j'y arrive?EOF signifie fin de fichier . Bien que je ne sache pas comment déclencher le symbole suivant, vous pouvez exécuter le programme suivant en canalisant un fichier, qui envoie le signal EOF à la fin:
où
a.out
est votre source compiléela source
read()
(syscall) reviendra0
, ce qui est interprété comme EOF: stackoverflow.com/a/1516177/4316166