Pourquoi getch() retourne avant d'appuyer sur une touche?
int main(int argc, char *argv[], char *env[])
{
printf("Press any key to exit.\n");
getch();
return 0;
}
Selon la page de man,
getch
doit attendre jusqu'à ce que vous appuyez sur une touche
...mais en fait, il renvoie directement avant d'appuyer sur une touche. (La valeur retournée est -1
).
Pourquoi?
Mise à jour
Je suis sur Linux. Comment puis-je mettre en œuvre Press any key to exit.
, si vous n'utilisez pas getch()
?
getchar()
retournera seulement après avoir appuyé sur Enter, ce n'est pas ce que je veux.
OriginalL'auteur new_perl | 2011-09-14
Vous devez vous connecter pour publier un commentaire.
Sur Linux,
getch()
est probablement lecurses
fonction, qui est assez différente de la Windows spécifique à la fonction du même nom.curses
(ncurses
) est probablement excessif pour ce que vous voulez faire.L'approche la plus simple serait d'attendre jusqu'à ce que l'utilisateur appuie sur Entrée, que vous pouvez faire comme ceci:
Si vous voulez vraiment à l'utilisateur d'être en mesure d'appuyer sur tout clé, non seulement Entrée, vous pouvez faire quelque chose comme ceci:
La deuxième
stty
est destiné à rétablir l'ats raisonnable de paramètres (il faut vraiment les restaurer à tout ce qu'ils étaient, mais la sauvegarde et la restauration de l'état est un peu plus compliqué). Il y a probablement nettoyeur de façons de le faire (en utilisant toutes les fonctions de la bibliothèque de lastty
programme utilise elle-même).EDIT: la Lecture d'un caractère unique, sans attendre Entrée est une question fréquemment posée. En fait, il est question de 19,1 dans le comp.lang.c FAQ.
EDIT2: je n'ai pas fait beaucoup de travail avec les malédictions récemment, mais j'ai juste fait un peu de jouer avec elle. Il semble que
getch()
ne fonctionnera pas à moins que vous appelez tout d'abordinitscr()
-- etinitscr()
efface l'écran. les malédictions est prévu pour une utilisation avec des applications comme les éditeurs de texte qui ont besoin de contrôle complet de l'écran. Il y a peut être un moyen d'utilisergetch()
sans prendre le contrôle de l'écran, mais je n'ai pas trouvé.La
system("stty ...")
quelque chose pourrait effectivement être la meilleure approche.EDIT3: La
termios
solution dans l'autre réponse est probablement le meilleur (system("stty ...")
est plus simple, mais en invoquant un programme externe se sent comme overkill.Comme dans le cas des OP commentaire "je ne peux pas croire
Press any key to exit.
est si ennuyeux de le faire en c", oui, c'est étrange, mais à la réflexion il y a des raisons valables pour elle.Prendre un regard sur les programmes installés sur un système Unix ou Linux. Je pense que vous trouverez que très peu d'entre eux requièrent ce type d'entrée (en attente pour une simple pression de touche).
Un grand nombre de programmes de travail avec les arguments de ligne de commande et de lecture de données à partir de fichiers ou de
stdin
. Tout ce que l'utilisateur de types de données d'entrée, pas de commandes ou des réponses aux invites.Certains programmes ne demander la confirmation pour certaines actions (les installateurs comme
apt-get
etcpan
souvent) - mais ils l'habitude de lire un ligne de l'entrée et de vérifier le premier caractère. Ou, pour certaines des mesures draconiennes, ils pourraient avoir besoin de taper le mot entier "oui", suivi par Entrée (vous ne voulez pas de reformater votre disque dur parce que vous avez accidentellement appuyé sur une touche).Bien sûr, beaucoup de programmes (éditeurs de texte, fichier de téléspectateurs) lire un seul caractère non-faisant écho à l'entrée, mais ces programmes ont tendance à être des malédictions; ils prennent le contrôle de la totalité de la fenêtre de terminal.
Enfin, un certain nombre de programmes ont interfaces GUI (navigateurs web, etc.); ils ne sont probablement même pas lire depuis l'entrée standard.
La plupart de la production Unix programmes n'utilisent pas ou besoin
Press any key to exit
invites. Ils font juste leur travail, souvent en silence, puis de résilier, de sorte que vous pouvez faire la chose suivante. Le besoin existe essentiellement pour les relativement élémentaire programmes, tels que les devoirs à la maison. Non pas qu'il n'y a rien de mal avec les devoirs à la maison, mais l'ensemble du système n'est pas conçu principalement pour soutenir une telle utilisation.Vraiment? Cela semble peu probable. Le document que vous l'avez mentionné se réfère à un 16-year-old Perl liaison de ncurses. Si il y avait un bug dans ncurses à l'époque, il ne devrait pas vous affecter maintenant, sauf si vous avez un très ancien système.
Je pense que vos attentes sont dans l'erreur. Dans votre programme d'origine, c'est se comporter exactement comme il est connu de se comporter. Comme je l'ai dit, les malédictions est probablement excessif pour ce que vous essayez de faire, mais si vous voulez l'utiliser, vous aurez besoin de lire la documentation. Il y a une bonne quantité de configuration que vous devez faire avant d'appeler
getch()
. Et voir mon dernier edit de ma réponse.Ce qui est malheureux, c'est que cette FAQ est quelque chose comme 30 ans et les personnes gardant toujours poser les mêmes foutues questions. 🙁
Je ne peux pas croire
Press any key to exit.
est si ennuyeux de le faire en c..OriginalL'auteur Keith Thompson
Voici un exemple minimal
Mais il ne semble pas être un moyen d'utiliser ncurses sans effacer l'écran. La Tache de Overkill, peut-être?!
Modifier
Voici une autre façon, je suis de travail. Ce n'utilise pas de malédictions, ni effacer l'écran.
La page de manuel dit cfmakeraw() peut ne pas être entièrement portable. Mais c'est juste un raccourci pour le réglage d'un gâchis de drapeaux:
initscr
wil effacer l'écran,provoquant étrange expérience..OriginalL'auteur luser droog