Wenn Ihr Linux kein conio.h
hat das kbhit()
unterstützt Sie können hier nach dem Code von Morgan Mattews suchen, um kbhit()
bereitzustellen Funktionalität in einer Weise, die mit jedem POSIX-kompatiblen System kompatibel ist.
Da der Trick das Puffern auf Termios-Ebene deaktiviert, sollte er auch die getchar()
lösen Problem wie hier gezeigt.
Das oben zitierte ncurses howto kann hilfreich sein. Hier ist ein Beispiel, das veranschaulicht, wie ncurses wie das conio-Beispiel verwendet werden könnte:
#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");
}
}
Beachten Sie, dass bei ncurses der iostream
Kopfzeile wird nicht verwendet. Das liegt daran, dass das Mischen von stdio mit ncurses zu unerwarteten Ergebnissen führen kann.
ncurses definiert übrigens TRUE
und FALSE
. Ein korrekt konfiguriertes ncurses verwendet den gleichen Datentyp für bool
von ncurses als C++-Compiler, der zum Konfigurieren von ncurses verwendet wird.
Eine kompakte Lösung basierend auf Christophes Antwort ist
#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;
}
Im Gegensatz zu dieser Antwort wird das Terminal nach dem Beenden des Programms nicht in einem seltsamen Zustand bleiben. Die Zeichen bleiben jedoch weiterhin im Eingabepuffer, sodass die gedrückte Taste unerwünschterweise in der nächsten Eingabeaufforderungszeile angezeigt wird.
Eine andere Lösung, die dieses Problem behebt, ist
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;
}
Die Verwendung ist wie folgt
enable_raw_mode();
// ...
if (kbhit()) ...
// ...
disable_raw_mode();
tcflush(0, TCIFLUSH); // Clear stdin to prevent characters appearing on prompt
Jetzt werden alle Zeichen, die zwischen der Ausführung der ersten und letzten Zeile eingegeben wurden, nicht im Terminal angezeigt. Wenn Sie jedoch mit Strg+C beenden, ist das Terminal ist in einem seltsamen Zustand zurückgelassen. (Seufz)