C select () timeout STDIN caractère unique (non ENTER)

Je veux pouvoir utiliser select() pour travailler avec la saisie d’un seul caractère (pas ENTER) à partir de STDIN.

Ainsi, lorsqu’un utilisateur appuie sur une seule touche, select() doit revenir immédiatement, sans attendre que l’utilisateur appuie sur la touche Entrée.

 int main(void) { fd_set rfds; struct timeval tv; int retval; /* Watch stdin (fd 0) to see when it has input. */ FD_ZERO(&rfds); FD_SET(0, &rfds); /* Wait up to 2 seconds. */ tv.tv_sec = 2; tv.tv_usec = 0; retval = select(1, &rfds, NULL, NULL, &tv); if (retval == -1) perror("select()"); else if (retval) printf("Data is available now.\n"); else printf("No data within five seconds.\n"); exit(EXIT_SUCCESS); } 

Cela fonctionne mais vous devez appuyer sur la touche Entrée pour terminer. Je veux juste que la sélection n’attende pas que l’utilisateur appuie sur la touche, puis sur ENTER.

Merci.

Je crois que lorsqu’une clé est entrée dans le terminal, elle est mise en mémoire tampon jusqu’à ce que vous appuyiez sur ENTREE, c’est-à-dire qu’en ce qui concerne le programme, vous n’avez rien entré. Vous voudrez peut-être jeter un coup d’oeil rapide à cette question .

Dans un environnement de type Unix, cela peut être accompli via les fonctions termios .

Vous devez désactiver le mode canonique, qui est la fonctionnalité de terminal qui permet l’édition en ligne avant que votre programme ne voie une entrée.

 #include  #include  int main(int argc, char **argv) { /* Declare the variables you had ... */ struct termios term; tcgetattr(0, &term); term.c_iflag &= ~ICANON; term.c_cc[VMIN] = 0; term.c_cc[VTIME] = 0; tcsetattr(0, TCSANOW, &term); /* Now the rest of your code ... */ } 

Détecter les erreurs qui pourraient provenir des appels tcgetattr et tcsetattr rest un exercice pour le lecteur.