Question

J'ai commencé à lire le langage de programmation C . (K & amp; R) et moi avons un doute sur la fonction getchar () .

Par exemple ce code:

#include <stdio.h>

main()
{
  int c;

  c = getchar();
  putchar(c);
  printf("\n");   
}

La saisie de toomanychars + CTRL + D (EOF) imprime uniquement t . Je pense que c'est prévu puisque c'est le premier personnage introduit.

Mais ensuite, cet autre morceau de code:

#include <stdio.h>

main()
{
  int c;

  while((c = getchar()) != EOF) 
    putchar(c);
}

Taper toomanychars + CTRL + D (EOF) imprime toomanychars .

Ma question est la suivante: pourquoi cela se produit-il si je ne possède qu'une seule variable de caractère? où sont stockés les autres caractères?

EDIT:

Merci à tous pour les réponses, je commence à l'obtenir maintenant ... une seule prise:

Le premier programme se ferme lorsque CTRL + D est donné, tandis que le second imprime la chaîne entière puis attend une nouvelle saisie de l'utilisateur. Pourquoi attend-il une autre chaîne et ne se ferme-t-il pas comme le premier?

Était-ce utile?

La solution

Il traite le flux d’entrée comme un fichier. C’est comme si vous ouvriez un fichier contenant le texte "toomanychars". et lu ou sorti un caractère à la fois.

Dans le premier exemple, en l'absence d'une boucle while, c'est comme si vous ouvriez un fichier et lisiez le premier caractère, puis que vous le sortiez. Cependant, le deuxième exemple continuera à lire les caractères jusqu'à l'obtention d'un signal de fin de fichier ( ctrl + D dans votre cas), comme s'il lisait à partir d'un fichier sur le disque.

En réponse à votre question mise à jour, quel système d'exploitation utilisez-vous? Je l'ai exécuté sur mon ordinateur portable Windows XP et cela a bien fonctionné. Si j'appuyais sur entrée, cela imprimerait ce que j'avais jusqu'à présent, créer une nouvelle ligne, puis continuer. (La fonction getchar () ne retourne pas tant que vous n’avez pas appuyé sur Entrée, c’est-à-dire quand il n’ya rien dans le tampon d’entrée quand il est appelé). Lorsque j'appuie sur CTRL + Z (EOF sous Windows), le programme se termine. Notez que sous Windows, le fichier EOF doit figurer sur une ligne distincte pour compter comme fichier EOF dans l'invite de commande. Je ne sais pas si ce comportement est imité sous Linux, ou quel que soit le système que vous utilisez.

Autres conseils

getchar obtient un seul caractère de l'entrée standard, qui est dans ce cas la mémoire tampon du clavier.

Dans le deuxième exemple, la fonction getchar est dans une boucle while qui continue jusqu'à ce qu'elle rencontre un EOF , de sorte qu'elle continue à fonctionner en boucle. et récupérez un caractère (et imprimez-le à l'écran) jusqu'à ce que l'entrée soit vide.

Les appels successifs à getchar obtiendront des caractères successifs provenant de l'entrée.

Oh, et ne vous sentez pas mal d'avoir posé cette question - j'étais également perplexe lorsque j'ai rencontré ce problème pour la première fois.

Quelque chose ici est tamponné. par exemple. La stdout FILE * à laquelle putchar écrit pourrait être line.buffered. Lorsque le programme se termine (ou rencontre une nouvelle ligne), un tel FICHIER * sera fflush () et vous verrez le résultat.

Dans certains cas, le terminal que vous visualisez peut mettre la sortie en mémoire tampon jusqu'à la fin d'une nouvelle ligne ou jusqu'à ce que le terminal lui-même soit invité à vider sa mémoire tampon, ce qui peut être le cas lorsque le programme de premier plan se ferme car il souhaite nouvelle invite.

Maintenant, ce qui est probablement le cas ici, c’est que c’est l’entrée qui est tamponnée (en plus de la sortie :-)). Lorsque vous appuyez sur les touches, cela apparaît dans la fenêtre de votre terminal. Cependant, le terminal n'enverra pas ces caractères à votre application, il le mettra en mémoire tampon jusqu'à ce que vous lui ordonniez d'être la fin de la saisie avec Ctrl + D, et éventuellement une nouvelle ligne. Voici une autre version sur laquelle réfléchir et réfléchir:

int main() {
  int c;
   while((c = getchar()) != EOF) {
     if(c != '\n')
        putchar(c);
   }
    return 0;
}

Essayez de nourrir votre programme avec une phrase et appuyez sur Entrée. Et faites de même si vous commentez if (c! = '\ n') Peut-être pouvez-vous déterminer si votre entrée, votre sortie ou les deux sont en quelque sorte tamponnés. Cela devient plus intéressant si vous utilisez ce qui précède comme ceci: ./mytest | ./mytest

(Notez également que CTRD + D n'est pas un caractère, pas plus que EOF. Mais sur certains systèmes, il en résultera la fermeture du flux d'entrée, ce qui déclenchera à nouveau une EOF pour ceux qui tenteront de lire à partir du flux.)

Votre premier programme ne lit qu'un caractère, l'imprime et se ferme. Votre deuxième programme a une boucle. Il continue à lire les caractères un à un et à les imprimer jusqu'à lire un caractère EOF. Un seul caractère est stocké à la fois.

Vous utilisez uniquement la variable c pour contenir chaque caractère un à la fois.

Une fois que vous avez affiché le premier caractère ( t ) à l'aide de putchar (c) , vous oubliez la valeur de c en affectant le caractère suivant ( o ) dans la variable c , en remplacement de la valeur précédente ( t ).

le code est fonctionnellement équivalent à

main(){
  int c;
  c = getchar();
  while(c != EOF) {
    putchar(c);
    c = getchar();
  }
}

vous pourriez trouver cette version plus facile à comprendre. la seule raison de placer l'affectation dans la condition est d'éviter de devoir taper deux fois 'c = getchar ()'.

Pour votre question mise à jour, dans le premier exemple, un seul caractère est lu. Il n'atteint jamais l'EOF. Le programme se termine car il n’a rien à faire après avoir terminé l’instruction printf. Il ne lit qu'un caractère. L'imprime. Met dans une nouvelle ligne. Et puis se termine car il n’a plus rien à faire. Il ne lit pas plus d'un caractère.

Considérant que, dans le second code, getchar et putchar sont présents dans une boucle while. En cela, le programme continue à lire les caractères un par un (comme le fait la boucle) jusqu'à atteindre le caractère EOF (^ D). À ce stade, il correspond à c! = EOF et, comme les conditions ne sont pas remplies, il sort de la boucle. Maintenant, il n'y a plus d'autres instructions à exécuter. Donc, le programme se termine à ce stade.

J'espère que cela vous aidera.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top