Pokud váš linux nemá conio.h
který podporuje kbhit()
zde můžete vyhledat kód Morgana Mattewse, který poskytne kbhit()
funkčnost způsobem kompatibilním s jakýmkoli systémem kompatibilním s POSIX.
Protože trik deaktivuje ukládání do vyrovnávací paměti na úrovni termios, měl by také vyřešit getchar()
problém, jak je ukázáno zde.
Výše uvedené postupy ncurses mohou být užitečné. Zde je příklad ilustrující, jak lze použít ncurses jako příklad 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");
}
}
Všimněte si, že u ncurses je iostream
záhlaví se nepoužívá. Je to proto, že smíchání stdio s ncurses může mít neočekávané výsledky.
ncurses, mimochodem, definuje TRUE
a FALSE
. Správně nakonfigurovaný ncurses použije stejný datový typ pro ncurses' bool
jako kompilátor C++ používaný pro konfiguraci ncurses.
Kompaktní řešení založené na Christopheově odpovědi je
#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;
}
Na rozdíl od této odpovědi to nezanechá terminál v podivném stavu po ukončení programu. Stále však nechává znaky sedět ve vstupní vyrovnávací paměti, takže stisknutá klávesa se nevítaně objeví na dalším řádku výzvy.
Jiné řešení, které řeší tento problém, je
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;
}
Použití je následující
enable_raw_mode();
// ...
if (kbhit()) ...
// ...
disable_raw_mode();
tcflush(0, TCIFLUSH); // Clear stdin to prevent characters appearing on prompt
Nyní se v terminálu nezobrazí žádné znaky zadané mezi provedením prvního a posledního řádku. Pokud však ukončíte pomocí Ctrl+C, terminál je zůstal v podivném stavu. (Povzdech)