J'essaie de comprendre getchar() != EOF
Je suis en train de lire Le Langage de Programmation C et ont tout compris à ce jour.
Cependant, quand je suis tombé sur le getchar()
et putchar()
, je n'ai pas réussi à comprendre quel est leur usage, et, plus précisément, ce que le code suivant ne.
main()
{
int c;
while ((c = getchar()) != EOF)
putchar(c);
}
Je comprends la main()
fonction, la déclaration de l'entier c
et la while
boucle. Pourtant, je suis confus au sujet de la condition à l'intérieur de la while
boucle. Qu'est-ce que l'entrée dans ce code en C, et qu'est-ce que la sortie.
Désolé si c'est une base et question stupide, mais je suis à la recherche d'une explication simple avant de passer dans le livre et de devenir plus confuse.
- Il a juste des échos de retour ce que vous tapez dans le terminal. Jusqu'à ce que vous atteignez la fin de saisie de code de contrôle. Ctrl+Z sur Windows, Ctrl+D sur *nix.
Vous devez vous connecter pour publier un commentaire.
Ce code peut être écrit plus clairement que:
La
EOF
caractère est reçu lorsqu'il n'y a plus d'entrée. Le nom fait plus de sens dans le cas où l'entrée est en cours de lecture d'un fichier réel, plutôt que de la saisie de l'utilisateur (qui est un cas particulier d'un fichier).[En aparté, en général, le
main
fonction devrait être écrit commeint main(void)
.]EOF
n'est pas un personnage.getchar()
est une fonction qui lit un caractère de entrée standard.EOF
est un caractère spécial utilisé dans C à l'état que la FIN DE FICHIER a été atteint.Habituellement, vous obtiendrez un
EOF
caractère de retour degetchar()
lors de votre entrée standard est autre que la console (c'est à dire, un fichier).Si vous exécutez votre programme sous unix comme ceci:
Alors votre
getchar()
sera de retour chaque caractère unique danssomefile
etEOF
dès quesomefile
se termine.Si vous exécutez votre programme comme ceci:
Et envoyer un
EOF
par le biais de la console (en tapantCTRL+D
dans Unix ou CTRL+Z dans Windows), puisgetchar()
également retourneEOF
et l'exécution sera la fin.getchar()
. Lit le fichier(entrée). Lit à partir du clavier(entrée)./your_program < input_file
Peut-être que vous avez confondu par le fait que la saisie de -1 sur la ligne de commande ne signifie pas la fin de votre programme? Parce que
getchar()
lit ce que les deux caractères, - et 1. Dans l'attribution de c, le caractère est converti en ASCII valeur numérique. Cette valeur numérique est stockée dans un emplacement mémoire, accessible par la c.Puis
putchar(c)
récupère cette valeur, regarde la table ASCII et les convertit en revenir au personnage, qui est imprimé.Je suppose que de trouver la valeur -1 décimale dans la table ASCII est impossible, parce que le tableau commence à 0. Donc
getchar()
a de compte pour les différentes solutions à différentes plates-formes. peut-être qu'il est ungetchar()
version pour chaque plate-forme?Je viens de trouver étrange que cette EOF n'est pas dans l'ordinaire de l'ascii. Il pourrait avoir été l'un des premiers personnages, qui ne sont pas imprimables. Par exemple, à la Fin de la ligne est en ASCII.
Ce qui se passe si vous transférez vos fichiers à partir de windows à linux? Va EOF caractères du fichier sera mis à jour automatiquement?
getchar() fonction lit un caractère au clavier (c'est à dire,
stdin
)Dans la condition à l'intérieur de la
while
boucle,getchar()
est appelée avant chaque itération et la valeur reçue est affecté à l'entierc
.Maintenant, il faut comprendre que, dans C, l'entrée standard (
stdin
) est comme un fichier. c'est à dire, l'entrée est mis en mémoire tampon. Entrée restera dans la mémoire tampon jusqu'à ce qu'il est réellement consommé.stdin
est en fait le flux d'entrée standard.getchar()
renvoie la la prochaine valeur disponible dans la mémoire tampon d'entrée.En substance le programme affiche tout ce qui a été lu à partir du clavier; y compris l'espace blanc comme
\n
(saut de ligne), de l'espace, etc.c'est à dire, l'entrée est l'entrée qui fournit de l'utilisateur via le clavier (
stdin
signifie généralement clavier).Et le résultat est ce que nous fournissons à l'entrée.
L'entrée que nous offrons est la lecture caractère par caractère & traités comme des personnages, même si nous leur donnons comme des nombres.
getchar()
sera de retourEOF
seulement si la fin de fichier est atteinte. Le fichier qui nous intéresse ici est lastdin
lui-même (entrée standard).Imaginer un fichier existant où l'entrée que nous fournissez par l'intermédiaire du clavier est stockée. C'est
stdin
.Ce "fichier", c'est comme un infini fichier. Donc pas de
EOF
.Si nous fournir le plus d'entrée que
getchar()
peut gérer à un moment (avant de le donner comme entrée en appuyant sur entrée), les valeurs seront toujours stockées dans la mémoire tampon d'entrée non consommées.Le
getchar()
va lire le premier caractère de l'entrée, de le stocker dansc and print
cwith
putchar(c)`.Au cours de la prochaine itération de la
while
boucle, les caractères supplémentaires donné lors de l'itération précédente qui sont encore enstdin
sont prises au cours dewhile ((c = getchar()) != EOF)
avec lec=getchar()
partie.Maintenant, le même processus est répété jusqu'à il n'y a plus rien dans la mémoire tampon d'entrée.
De ce fait, il regarder comme si
putchar()
est de retourner une chaîne de caractères au lieu d'un seul caractère à la fois si plus d'un caractère est donnée en entrée lors d'une itération.Par exemple: si l'entrée était
abcdefghijkl
la sortie aurait été la même
abcdefghijkl
Si vous ne voulez pas ce comportement, vous pouvez ajouter fflush(stdin); à droite après le
putchar(c);
.Ce sera la cause de la boucle pour imprimer uniquement le premier caractère de l'entrée fournie lors de chaque itération.
Par exemple: si l'entrée était
adgbad
seulement
a
sera imprimé.L'entrée est envoyé à
stdin
seulement après que vous appuyez sur entrée.putchar() est à l'opposé de
getchar()
. Il écrit la sortie dans le flux de sortie standard (stdout
, généralement le moniteur).
n'est pas un personnage présent dans le fichier. C'est quelque chose retourné par la fonction comme un code d'erreur.EOF
Vous ne serez probablement pas en mesure de sortir de la donner
while
boucle normalement. La mémoire tampon d'entrée sera vidé (pour l'affichage à la sortie), dès que quelque chose vient à elle via le clavier et lastdin
de ne pas donnerEOF
.De la main à la sortie de la boucle,
EOF
peuvent être envoyés en utilisant le clavier en appuyant surctrl+D sous Linux et
ctrl+Z dans Windows
par exemple:
Si vous appuyez sur la combinaison de touches pour donner
EOF
, le messageGot past!
sera affiché avant de quitter le programme.Si
stdin
est pas déjà vide, vous devrez appuyez sur cette combinaison de touches deux fois. Une fois pour effacer cette mémoire tampon, puis à simuateEOF
.EDIT: La paire de parenthèses autour de
c = getchar()
danswhile ((c = getchar()) != EOF)
est de faire en sorte que la valeur retournée pargetchar()
est d'abord affecté àc
avant que valeur est comparée avecEOF
.Si cette parenthèse supplémentaires n'étaient pas là, l'expression aurait effectivement été
while (c = (getchar() != EOF) )
qui aurait signifié quec
pourrait avoir une des 2 valeurs:1
(true) ou0
(pour de faux) qui n'est évidemment pas ce qui est prévu.Le code écrit avec C en cours des normes devrait être
La boucle peut être réécrit comme
cela se lit comme
c
c
en sortie standardDe nombreux langages de programmation gérer des conditions exceptionnelles à travers le déclenchement d'exceptions que briser le flux de programme normal. C il n'y a pas une telle chose. Au lieu de cela, les fonctions qui peuvent échouer ont une valeur de retour et toutes les conditions exceptionnelles sont signalés par une valeur de retour, qui vous avez besoin de vérifier à partir de la documentation de la fonction donnée. En cas de
getchar
, la documentation de la norme C11 dit (C11 7.21.7.6p3):Il est dit ailleurs que
EOF
est une constante entière qui est < 0, et les plus ordinaires de la valeur de retour est >= 0 - launsigned char
zéro étendu à unint
.Du stream à la fin-de-fichier signifie que tous les commentaires ont été consommés. Pour l'entrée standard, il est possible de provoquer ce à partir du clavier en tapant Ctrl+D sous Unix/Linux bornes et Ctrl+Z dans la console Windows windows. Une autre possibilité pourrait être le programme pour recevoir l'entrée à partir d'un fichier ou d'un tuyau au lieu de partir du clavier, puis à la fin-de-fichier doit être signalé à chaque fois que l'entrée ont été entièrement consommé, c'est à dire
ou
Que le fragment ci-dessus dit, il ya en fait deux différentes conditions qui peuvent causer des
getchar
de retourEOF
: soit la fin-de-fichier a été atteint, ou une erreur s'est produite. Ce ne peut pas être déduite de la valeur de retour seul. Au lieu de cela, vous devez utiliser les fonctionsfeof
etferror
.feof(stdin)
doit retourner une valeur vrai si la fin de fichier a été atteinte sur l'entrée standard.ferror(stdin)
serait retourner true si une erreur s'est produite.Si une erreur s'est produite, la variable
errno
défini par<errno.h>
contiendra le code d'erreur; la fonctionperror
peut être utilisé pour afficher automatiquement un lisible message d'erreur avec un préfixe. Ainsi, nous pourrions étendre l'exemple dePour déclencher la fin-de-fichier, on peut utiliser les touches Ctrl+D (ici affichés comme
^D
) sur une nouvelle ligne sur Linux:(remarquez comment le entrée ici est la ligne de tampon, de sorte que l'entrée n'est pas entrelacée à l'intérieur de la ligne de sortie).
De la même façon, nous pouvons obtenir le même effet en utilisant un pipeline.
Déclencher une erreur est un peu plus compliqué. Dans
bash
etzsh
coquilles de l'entrée standard peut être fermé sorte qu'il ne peut pas venir de n'importe où, grâce à l'ajout<&-
à la ligne de commande:Mauvais descripteur de fichier, ou
EBADF
signifie que le entrée standard - descripteur de fichier nombre 0 n'est pas valide, car il n'était pas ouvert à tous.Une autre façon amusante de générer une erreur serait de lire l'entrée standard d'un répertoire - ce qui provoque errno à être mis à
EISDIR
sur Linux:En fait la valeur de retour de
putchar
doivent aussi être vérifiés - il de mêmeretourne
EOF
en cas d'erreur, ou le caractère écrit:Et maintenant, nous pouvons tester cela en redirigeant la sortie standard vers
/dev/full
- il y a cependant un gotcha - depuis la sortie standard est mis en mémoire tampon, il nous faut écrire assez à cause de la mémoire tampon à rincer immédiatement et non pas à la fin du programme. Nous obtenons infini zéro octets de/dev/zero
:P. S. il est très important de toujours utiliser une variable de type
int
pour stocker la valeur de retour degetchar()
. Même si il lit un caractère, à l'aide deconnecté
/unsigned
/plainchar
est toujours mauvais.Dans une manière similaire à l' | tuyau de commande ci-dessus, vous pouvez utiliser la redirection sur votre système pour utiliser le code ci-dessus pour afficher tous les caractères contenu d'un fichier, jusqu'à ce qu'il atteigne la fin (EOF), représenté par CTRL-Z ou CTRL-D en général.
Dans la console:
ProgramName < FileName1.txt
Et pour créer une copie de ce qui est lu dans Fichier1, vous pouvez:
ProgramName < FileName1.txt > CopyOfInput.txt
Cela démontre votre programme, de multiples façons, nous l'espérons l'aide de votre compréhension.
-Hope qui aide.
En fait c=getchar() fournit le caractère que l'utilisateur entre sur la console et que la valeur est vérifiée avec des expressions du FOLKLORE qui représente la Fin De Fichier . EOF est rencontré au dernier de fichier. (c = getchar()) != EOF est équivalent à c != EOF . Maintenant, je pense que c'est beaucoup plus facile . Si vous avez toute autre question, laissez-moi savoir.
devient un personnage à partir d'une entrée.
La valeur de cette mission est la valeur de la gauche après la cession, ou la valeur du caractère qui a été lu. La valeur de
EOF
est par défaut-1
.Tant que la valeur reste quelque chose d'autre que
EOF
ou, en d'autres termes, tant que la condition reste vraie, la boucle va continuer à itérer. Une fois la valeur devientEOF
la valeur de l'ensemble de l'état de la0
et il va se casser la boucle.Supplémentaires parenthèses autour de
c = getchar()
sont pour le compilateur, pour souligner que nous voulions vraiment faire une affectation à l'intérieur de l'état, parce qu'il suppose généralement que vous vouliez type==
et vous avertit.Donc l'ensemble du code en fait des échos à ce que vous avez entrée. Il affecte la valeur des caractères à
c
à l'intérieur de l'état, puis les sorties en arrière dans le corps de la boucle, la fin seulement lorsque la fin de fichier est détecté.