Si votre Linux n'a pas de conio.h
qui prend en charge kbhit()
vous pouvez chercher ici le code de Morgan Mattews pour fournir kbhit()
fonctionnalité d'une manière compatible avec n'importe quel 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 getchar()
problème comme démontré ici.
Le guide ncurses 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, le iostream
l'en-tête n'est pas utilisé. En effet, mélanger 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 comme compilateur C++ utilisé pour configurer ncurses.
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 fermeture 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 prochaine ligne d'invite.
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, tous les caractères saisis entre l'exécution de la première et de la dernière ligne n'apparaîtront pas dans le terminal. Cependant, si vous quittez avec Ctrl+C le terminal est laissé dans un état bizarre. (Soupir)