Utiliser kbhit () et getch () sous Linux

Sous Windows, j’ai le code suivant pour rechercher des entrées sans interrompre la boucle:

#include  #include  #include  int main() { while (true) { if (_kbhit()) { if (_getch() == 'g') { std::cout << "You pressed G" << std::endl; } } Sleep(500); std::cout << "Running" << std::endl; } } 

Cependant, vu qu’il n’y a pas de conio.h , conio.h la manière la plus simple de réaliser cette même chose sous Linux?

Les instructions citées ci-dessus peuvent être utiles. Voici un exemple illustrant comment ncurses pourrait être utilisé comme l’exemple conio:

 #include  int main() { initscr(); cbreak(); noecho(); scrollok(stdscr, TRUE); nodelay(stdscr, TRUE); while (true) { if (getch() == 'g') { printw("You pressed G\n"); } napms(500); printw("Running\n"); } } 

Notez qu’avec ncurses, l’en-tête iostream n’est pas utilisé. C’est parce que le mixage de stdio avec ncurses peut avoir des résultats inattendus.

Au fait, ncurses définit TRUE et FALSE . Un ncurses correctement configuré utilisera le même type de données pour le bool de ncurses que le compilateur C ++ utilisé pour configurer ncurses.

Si votre Linux n’a pas de conio.h qui supporte kbhit() vous pouvez chercher ici le code de Morgan Mattews pour fournir la fonctionnalité kbhit() de manière compatible avec tout système compatible POSIX.

Comme l’astuce désactive la mise en mémoire tampon au niveau termios, elle devrait également résoudre le problème de getchar() , comme démontré ici .

Bien que l’utilisation de ncurses soit fonctionnellement équivalente à l’API Turbo C “conio.h”, une solution plus complète consiste à utiliser une implémentation conio, comme on peut le trouver ici .

Vous le téléchargez et l’utilisez dans votre programme pour une implémentation très complète de l’interface conio, sous Linux. (Ou OSX.) Écrit par Ron Burkey.

Une solution compacte basée sur la réponse de Christophe est

 #include  #include  bool kbhit() { termios term; tcgetattr(0, &term); termios term2 = term; term2.c_lflag &= ~ICANON; tcsetattr(0, TCSANOW, &term2); int byteswaiting; ioctl(0, FIONREAD, &byteswaiting); tcsetattr(0, TCSANOW, &term); return byteswaiting > 0; } 

Contrairement à cette réponse, cela ne laissera pas le terminal dans un état étrange après la fin du programme. Cependant, les caractères restnt toujours dans le tampon de saisie, de sorte que la touche qui a été pressée apparaîtra difficilement sur la ligne suivante.

Une autre solution qui résout ce problème est

 void enable_raw_mode() { termios term; tcgetattr(0, &term); term.c_lflag &= ~(ICANON | ECHO); // Disable echo as well tcsetattr(0, TCSANOW, &term); } void disable_raw_mode() { termios term; tcgetattr(0, &term); term.c_lflag |= ICANON | ECHO; tcsetattr(0, TCSANOW, &term); } bool kbhit() { int byteswaiting; ioctl(0, FIONREAD, &byteswaiting); return byteswaiting > 0; } 

L’utilisation est la suivante

 enable_raw_mode(); // ... if (kbhit()) ... // ... disable_raw_mode(); tcflush(0, TCIFLUSH); // Clear stdin to prevent characters appearing on prompt 

Désormais, aucun caractère saisi entre l’exécution de la première et de la dernière ligne n’apparaîtra dans le terminal. Cependant, si vous quittez avec Ctrl + C, le terminal rest dans un état étrange. (Soupir)