2
votes

Exploration de la fonction getchar ()

Je suis intéressé par C donc je veux explorer plus sur C en particulier C89 pour voir comment ce langage a changé au fil du temps :). J'ai acheté "Le langage de programmation C" (2ème édition) de Denis Ritchie.

Un exemple dans le livre m'amène à une situation compliquée concernant la fonction getchar ().

Exemple 1 qui est mon exemple après avoir lu le livre est:

a
'\n' character in c: 0
'\n' character in c: 1

La sortie de l'exemple 1 est:

#include <stdio.h>

int main()
{
    int c;

    while ((c = getchar()) != EOF) {
        printf("\'\\n\' character in c: %d\n", c == '\n');
    }
}

Dans ce cas, la sortie ne ne montre aucun caractère de nouvelle ligne dans cette entrée. CEPENDANT, un autre exemple que j'essaye est:

a
'\n' character in c: 0
'\n' character in c: 0

et la sortie du code est:

#include <stdio.h>

int main()
{
    int c = getchar();
    printf("\'\\n\' character in c: %d\n", c == '\n');
    printf("\'\\n\' character in c: %d\n", c == '\n');
}

Je ne le fais pas comprendre pourquoi le deuxième exemple duplique la fonction printf () et comment il pourrait lire le caractère '\ n' quand il entre dans la boucle. Pendant ce temps, le premier exemple ne montre rien concernant le caractère '\ n'


4 commentaires

Cela a à voir avec le flux d'entrée; le / n est toujours laissé dans le flux d'entrée après le premier appel.


Dans le premier code, vous vérifiez simplement que a deux fois, tandis que dans le deuxième code, il vérifie le a , puis le \ n .


M. @Blaze, pouvez-vous m'expliquer comment fonctionne la mémoire dans les deux situations? Merci


La réponse de Lundin couvre bien cela. La raison pour laquelle il ne vérifie pas le \ n dans le premier exemple est que vous ne lui dites pas de le faire. int c = getchar (); récupère le a dans c , puis vous le vérifiez deux fois. Vous ne lisez jamais ce \ n . Vous vouliez probablement un autre c = getchar (); après la première impression.


3 Réponses :


1
votes

Vous appuyez sur Entrée après avoir entré a .

Ainsi, votre flux d'entrée aura " a \ n ".

while ((c = getchar()) != EOF) {


0 commentaires

2
votes
  • Vous tapez a et appuyez sur Entrée. Le tampon stdin ressemblera alors à a , \ n , deux caractères.
  • Premier tour de la boucle, c est de la valeur 'a' , qui n'est pas égale à '\ n' , sortie 0.
  • Tour suivant dans la boucle, c est de la valeur '\ n' , qui est égale à '\ n' , sortie 1.
  • En fin de saisie, lorsque c devient EOF , le printf n'est jamais exécuté.

2 commentaires

Je vous remercie. Mais pourquoi le premier exemple ne vérifie-t-il pas le caractère '\ n'?


Ce n'est pas le cas parce que vous ne demandez un personnage qu'une seule fois. getchar () renvoie un seul caractère à la fois et tous les caractères restants sont laissés sur la chaîne d'entrée pour être consommés par les appels ultérieurs de getchar.



0
votes

Prenez votre deuxième exemple, à savoir

c = getchar();
if (c == EOF) return 0;
printf("\'\\n\' character in c: %d\n", c == '\n');
c = getchar();
if (c == EOF) return 0;
printf("\'\\n\' character in c: %d\n", c == '\n');
c = getchar();
if (c == EOF) return 0;
printf("\'\\n\' character in c: %d\n", c == '\n');
... and so on ...

et déroulez la boucle. Cela deviendra:

while ((c = getchar()) != EOF) {
    printf("\'\\n\' character in c: %d\n", c == '\n');
}

Maintenant, comparez ceci à votre première version et vous verrez que la différence est que le deuxième exemple fait un appel getchar entre les printf alors que le premier exemple n'a qu'un seul getcharcall.

En d'autres termes - le premier exemple ne lit que le caractère 'a' tandis que le deuxième exemple lit d'abord le 'a' puis lit le '\ n' puis lit .... (peu importe ce que vous tapez ensuite) p >


0 commentaires