Se il tuo Linux non ha conio.h
che supporta kbhit()
puoi cercare qui il codice di Morgan Mattews per fornire kbhit()
funzionalità in un modo compatibile con qualsiasi sistema conforme a POSIX.
Poiché il trucco disattiva il buffering a livello termios, dovrebbe anche risolvere il getchar()
problema come dimostrato qui.
L'howto ncurses sopra citato può essere utile. Ecco un esempio che illustra come ncurses potrebbe essere usato come l'esempio 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");
}
}
Nota che con ncurses, il iostream
l'intestazione non viene utilizzata. Questo perché mischiare stdio con ncurses può avere risultati inaspettati.
ncurses, tra l'altro, definisce TRUE
e FALSE
. Un ncurses correttamente configurato utilizzerà lo stesso tipo di dati per bool
di ncurses come compilatore C++ usato per configurare ncurses.
Una soluzione compatta basata sulla risposta di Christophe è
#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;
}
A differenza di quella risposta, questo non lascerà il terminale in uno stato strano dopo che il programma è uscito. Tuttavia, lascia ancora i caratteri nel buffer di input, quindi il tasto che è stato premuto apparirà in modo indesiderato nella riga di prompt successiva.
Una soluzione diversa che risolve questo problema è
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'utilizzo è il seguente
enable_raw_mode();
// ...
if (kbhit()) ...
// ...
disable_raw_mode();
tcflush(0, TCIFLUSH); // Clear stdin to prevent characters appearing on prompt
Ora tutti i caratteri digitati tra l'esecuzione della prima e dell'ultima riga non verranno visualizzati nel terminale. Tuttavia, se esci con Ctrl+C il terminale è lasciato in uno stato strano. (Sospiro)