Quelle est la différence exacte entre les fonctions getch
et getchar
?
getchar()
est une fonction standard qui obtient un caractère de la stdin.
getch()
n'est pas standard. Il obtient un caractère du clavier (qui peut être différent de stdin) et ne l'écho pas.
La fonction C standard est getchar()
, déclarée dans <stdio.h>
. Il existe essentiellement depuis la nuit des temps. Il lit un caractère à partir de l'entrée standard (stdin
), qui est généralement le clavier de l'utilisateur, sauf s'il a été redirigé (par exemple via le caractère de redirection d'entrée du shell <
, Ou un canal).
getch()
et getche()
sont d'anciennes fonctions MS-DOS, déclarées dans <conio.h>
, et toujours populaires sur les systèmes Windows. Ce ne sont pas des fonctions C standard; ils n'existent pas sur tous les systèmes. getch
lit immédiatement une touche du clavier, sans attendre que l'utilisateur appuie sur la touche Retour, et sans faire écho à la touche. getche
est le même, sauf qu'il fait écho. Autant que je sache, getch
et getche
toujours lisent à partir du clavier; ils ne sont pas affectés par la redirection d'entrée.
La question se pose naturellement, si getchar
est la fonction standard, comment l'utilisez-vous pour lire un caractère sans attendre la touche Retour, ou sans faire écho? Et les réponses à ces questions sont au moins un peu compliquées. (En fait, ils sont suffisamment compliqués pour que je soupçonne qu'ils expliquent la popularité durable de getch
et getche
, qui, si rien d'autre n'est très facile à utiliser.)
Et la réponse est que getchar
n'a aucun contrôle sur les détails tels que l'écho et la mise en mémoire tampon des entrées - en ce qui concerne C, ce sont des problèmes de niveau inférieur dépendant du système.
Mais il est utile de comprendre le modèle d'entrée de base que getchar
suppose. De façon confuse, il existe généralement deux différents niveaux de mise en mémoire tampon.
Lorsque l'utilisateur tape des touches sur le clavier, elles sont lues par le pilote de terminal du système d'exploitation . En règle générale, dans son mode par défaut, le pilote de terminal répercute les frappes immédiatement lors de leur saisie (afin que l'utilisateur puisse voir ce qu'il tape). En règle générale, dans son mode par défaut, le pilote de terminal prend également en charge une certaine quantité d'édition de ligne - par exemple, l'utilisateur peut appuyer sur la touche Supprimer ou Retour arrière pour supprimer un caractère tapé accidentellement. Afin de prendre en charge l'édition de ligne, le pilote de terminal collecte généralement les caractères dans un tampon d'entrée . Ce n'est que lorsque l'utilisateur frappe Retour que le contenu de ce tampon est mis à la disposition du programme appelant. (Ce niveau de mise en mémoire tampon n'est présent que si l'entrée standard est en fait un clavier ou un autre périphérique série. Si l'entrée standard a été redirigée vers un fichier ou un canal, le pilote de terminal n'est pas en vigueur et ce niveau de mise en mémoire tampon ne s'applique pas.)
Le package stdio lit les caractères du système d'exploitation dans son propre tampon d'entrée. getchar
récupère simplement le caractère suivant de ce tampon. Lorsque le tampon est vide, le package stdio tente de le remplir en lisant plus de caractères dans le système d'exploitation.
Donc, si nous suivons ce qui se passe quand un programme appelle getchar
pour la première fois: stdio découvre que son tampon d'entrée est vide, alors il essaie de lire certains caractères du système d'exploitation, mais il n'y en a pas caractères encore disponibles, donc les appels read
. Pendant ce temps, l'utilisateur peut taper certains caractères, qui s'accumulent dans le tampon d'entrée du pilote de terminal, mais l'utilisateur n'a pas encore appuyé sur Retour. Enfin, l'utilisateur frappe Retour, et l'appel bloqué read
renvoie, renvoyant la valeur d'une ligne entière de caractères à stdio
, qui les utilise pour remplir sa mémoire tampon d'entrée, à partir de laquelle il renvoie ensuite le premier à cet appel initial à getchar
, qui a patiemment attendu tout ce temps. (Et puis si le programme appelle getchar
une deuxième ou troisième fois, il y a probablement quelques caractères supplémentaires - les caractères suivants sur le ligne saisie par l'utilisateur - disponible dans le tampon d'entrée de stdio pour que getchar
revienne immédiatement. Pour un peu plus à ce sujet, voir section 6.2 de ces notes de cours C =.)
Mais dans tout cela, comme vous pouvez le voir, getchar
et le package stdio n'ont aucun contrôle sur les détails comme l'écho ou la modification de la ligne d'entrée, car ceux-ci sont traités plus tôt, à un niveau inférieur, dans le pilote de terminal, dans étape 1.
Donc, au moins sous les systèmes d'exploitation Unix, si vous voulez lire un caractère sans attendre la touche Retour, ou contrôler si les caractères sont répétés ou non, vous le faites en ajustant le comportement du pilote de terminal. Les détails varient, mais il existe un moyen d'activer et de désactiver l'écho et un moyen (en fait de deux manières) d'activer et de désactiver l'édition de la ligne d'entrée. (Pour au moins certains de ces détails, voir cette SO question , ou question 19.1 dans l'ancien C FAQ list .)
Lorsque la modification de la ligne de saisie est désactivée, le système d'exploitation peut renvoyer des caractères immédiatement (sans attendre la touche Retour), car dans ce cas, il n'a pas à s'inquiéter que l'utilisateur ait tapé une mauvaise frappe qui doit être "prise" retour "avec la touche Supprimer ou Retour arrière. (Mais de la même manière, lorsqu'un programme désactive l'édition de la ligne d'entrée dans le pilote du terminal, s'il veut permettre à l'utilisateur de corriger les erreurs, il doit implémenter sa propre édition, car il va voir --- c'est-à-dire successif les appels à getchar
vont renvoyer - à la fois les mauvais caractères de l'utilisateur et le code de caractère pour la touche Supprimer ou Retour arrière .)
getch()
il obtient juste une entrée mais ne l'affiche jamais comme une sortie à l'écran malgré que nous appuyions sur une touche entrée.
getchar()
il obtient une entrée et l'affiche sur l'écran lorsque nous appuyons sur la touche entrée.
getchar
est le standard C, trouvé dans stdio.h. Il lit un caractère dans stdin
(le flux d'entrée standard = entrée de console sur la plupart des systèmes). Il s'agit d'un appel bloquant, car il nécessite que l'utilisateur saisisse un caractère, puis appuie sur Entrée. Il fait écho à l'entrée de l'utilisateur sur l'écran.
getc(stdin)
est 100% équivalent à getchar
, sauf qu'il peut également être utilisé pour d'autres flux d'entrée.
getch
n'est pas standard, généralement trouvé dans l'ancien en-tête MS DOS obsolète conio.h. Il fonctionne exactement comme getchar
sauf qu'il ne bloque pas après la première frappe, il permet au programme de continuer sans que l'utilisateur appuie sur Entrée. Il ne renvoie pas d'entrée à l'écran.
getche
est le même que getch
, également non standard, mais il fait écho à la saisie à l'écran.