GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Verwenden von kbhit() und getch() unter Linux

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)


Linux
  1. Debuggen Sie Linux mit ProcDump

  2. Überprüfen Sie den Speicherplatz in Linux mit den Befehlen df und du

  3. Installieren und Verwenden des Homebrew Package Managers unter Linux

  4. Verwenden von ssh-keygen und Sharing für die schlüsselbasierte Authentifizierung in Linux

  5. Überwachen Sie den Linux-Server mit Prometheus und Grafana

Erstellen Sie virtuelle CD- und DVD-Laufwerke mit CDEmu unter Linux

Greifen Sie unter Linux mit Xclip und Xsel auf den Inhalt der Zwischenablage zu

So sichern Sie Dateien und Verzeichnisse mit Rsync unter Linux

So führen Sie Linux-Apps unter Windows 10 und 11 mit WSL aus

So klonen und wiederherstellen Sie eine Linux-Partition mit dem dd-Befehl

So löschen Sie Dateien und Verzeichnisse mit der Linux-Befehlszeile