GNU/Linux >> Znalost Linux >  >> Linux

Použití kbhit() a getch() v Linuxu

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)


Linux
  1. Monitorujte linuxový server pomocí Prometheus a Grafana

  2. Automatizujte odezvu pomocí Expect a Autoexpect v Linuxu

  3. Nastavte systémové datum a čas pomocí C++ v Linuxu

  1. Ladění Linuxu pomocí ProcDump

  2. Zkontrolujte místo na disku v Linuxu pomocí příkazů df a du

  3. Použití rz a sz pod linuxovým shellem

  1. Instalace a používání Homebrew Package Manager v systému Linux

  2. Použití ssh-keygen a sdílení pro ověřování založené na klíčích v Linuxu

  3. Jak zkontrolovat OS a verzi pomocí příkazu Linux