Sous Windows, j'ai le code suivant pour rechercher une entrée sans interrompre la boucle:
#include <conio.h>
#include <Windows.h>
#include <iostream>
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
, quel est le moyen le plus simple de réaliser cette même chose sous Linux?
Le ncurses howto cité ci-dessus peut être utile. Voici un exemple illustrant comment ncurses pourrait être utilisé comme l'exemple conio:
#include <ncurses.h>
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é. En effet, le mélange de stdio avec ncurses peut avoir des résultats inattendus.
ncurses, soit dit en passant, définit TRUE
et FALSE
. Un ncurses correctement configuré utilisera le même type de données pour 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 regarder ici pour le code de Morgan Mattews pour fournir la fonctionnalité kbhit()
d'une manière compatible avec tout système compatible POSIX.
Comme l'astuce désactive la mise en mémoire tampon au niveau des termios, elle devrait également résoudre le problème de la getchar()
comme démontré ici .
Une solution compacte basée sur la réponse de Christophe est
#include <sys/ioctl.h>
#include <termios.h>
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, il laisse toujours les caractères assis dans le tampon d'entrée, de sorte que la touche qui a été enfoncée apparaîtra de manière indésirable sur la ligne d'invite suivante.
Une solution différente 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 est laissé dans un état étrange. (Soupir)
Alors que l'utilisation de ncurses est fonctionnellement équivalente à l'API Turbo C "conio.h", une solution plus complète consiste à utiliser une implémentation conio, comme cela peut être trouvé 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.