Quel est le but de Ungetc (ou Ungetch de K & R)?

Quelqu’un peut-il m’expliquer le but de l’ungetch? Ceci provient du chapitre 4 de K & R où vous créez une calculasortingce de polissage inversé.

J’ai exécuté le programme sans appeler à ungetch et dans mes tests, il fonctionne toujours de la même manière.

int getch(void) /* get a (possibly pushed back) character */ { if (bufp > 0) { return buf[--bufp]; } else { return getchar(); } } void ungetch(int c) /* push character back on input */ { if (bufp >= BUFSIZE) { printf("ungetch: too many characters\n"); } else { buf[bufp++] = c; } } 

(J’ai supprimé l’opérateur ternaire de getch pour le rendre plus clair.)

Je ne connais pas l’exemple spécifique auquel vous faites référence (cela fait probablement 23 ans que je lis K & R, et c’était la première édition.), Mais il est souvent pratique, lors de l’parsing syntaxique, de «regarder» le caractère suivant pour voir si cela fait partie de ce que vous parsingz actuellement. Par exemple, si vous lisez un numéro, vous voulez continuer à lire les chiffres jusqu’à ce que vous arriviez à un chiffre non numérique. Ungetc permet au lecteur de chiffres de regarder le caractère suivant sans le consumr afin que quelqu’un d’autre puisse le lire. Dans l’exemple de Greg Hewgill “2 3+”, le lecteur de numéro lit les 3 chiffres, lit le signe plus et sait que le nombre est terminé, puis supprime le signe plus afin qu’il puisse être lu ultérieurement.

Essayez d’exécuter le programme sans espaces autour des opérateurs. Je ne me souviens pas précisément du format de cet exemple et je ne dispose pas de K & R, mais au lieu d’utiliser “2 3 +”, essayez “2 3+”. ungetch() est probablement utilisé lors de l’parsing des numéros, car l’parsingur de numéros lira les chiffres jusqu’à obtenir un résultat non numérique. Si le non-chiffre est un espace, alors le prochain getch() lira le + et tout ira bien. Cependant, si le prochain non-chiffre est un + , il devra alors le repousser dans le stream d’entrée afin que la boucle de lecture principale puisse le retrouver.

J’espère que je me souviens de l’exemple correctement.

Il est beaucoup utilisé pour les scanners lexicaux (la partie du compilateur qui divise votre texte en morceaux tels que les noms de variables, les constantes, les opérateurs, etc.). La fonction n’est pas nécessaire pour le scanner, c’est très pratique.

Lorsque vous lisez un nom de variable, par exemple, vous ne savez pas quand vous avez terminé jusqu’à ce que vous lisiez un caractère qui ne peut pas faire partie du nom de la variable. Mais ensuite, vous devez vous souvenir de ce personnage et trouver un moyen de le communiquer à la prochaine tranche du lexer. Vous pouvez créer une variable globale ou autre chose, ou la transmettre à l’appelant, mais comment renvoyer d’autres éléments, tels que des codes d’erreur? Au lieu de cela, vous ungetch () le caractère pour le remettre dans le stream d’entrée, faites ce que vous devez avec votre nom de variable et retournez-le. Ensuite, lorsque le lexer commence à lire le morceau suivant, il n’a pas besoin de chercher des caractères supplémentaires.

Regardez ce code, vous comprendrez:

 #include  #include  int main() { int y=0; char t[10]; int u=0; ungetch('a'); t[y++]=getch(); ungetch('m'); t[y++]=getch(); ungetch('a'); t[y++]=getch(); ungetch('z'); t[y++]=getch(); ungetch('z'); t[y++]=getch(); ungetch('a'); t[y++]=getch(); ungetch('l'); t[y++]=getch(); ungetch('\0'); t[y++]=getch(); ungetch('\0'); t[y++]=getch(); ungetch('\0'); t[y++]=getch(); printf("%s",t); return 0; }