GNU/Linux >> Linux の 問題 >  >> Linux

Linux で kbhit() と getch() を使用する

Linux に conio.h がない場合 kbhit() をサポートする kbhit() を提供する Morgan Mattews のコードについては、こちらを参照してください。 あらゆる POSIX 準拠システムと互換性のある方法で機能します。

termios レベルでバッファリングを非アクティブ化するトリックとして、getchar() も解決する必要があります。 ここに示されている問題。


上で引用した ncurses のハウツーが役に立ちます。以下は、conio の例のように ncurses を使用する方法を示す例です:

#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");
    }
}

ncurses では、iostream ヘッダーは使用しません。これは、stdio と ncurses を混在させると、予期しない結果が生じる可能性があるためです。

ちなみに、ncurses は TRUE を定義しています および FALSE .正しく構成された ncurses は、ncurses の bool に同じデータ型を使用します。 ncurses の設定に使用される C++ コンパイラとして。


クリストフの答えに基づくコンパクトなソリューションは

#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;
}

その答えとは異なり、これにより、プログラムが終了した後に端末が奇妙な状態になることはありません。ただし、文字は入力バッファに残っているため、押されたキーが次のプロンプト行に表示されます。

この問題を解決する別の解決策は

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;
}

使い方は以下の通りです

enable_raw_mode();
// ...
if (kbhit()) ...
// ...
disable_raw_mode();
tcflush(0, TCIFLUSH); // Clear stdin to prevent characters appearing on prompt

これで、最初の行と最後の行の実行の間に入力された文字はターミナルに表示されなくなります。ただし、Ctrl+C で終了すると、ターミナルは 変な状態のまま。 (ため息)


Linux
  1. LinuxでのHomebrewPackageManagerのインストールと使用

  2. PrometheusとGrafanaを使用してLinuxサーバーを監視する

  3. Linux シェルで rz と sz を使用する

  1. ProcDumpを使用してLinuxをデバッグする

  2. dfおよびduコマンドを使用してLinuxのディスク容量を確認する

  3. Linuxでのキーベースの認証にssh-keygenと共有を使用する

  1. LinuxでExpectとAutoexpectを使用して応答を自動化する

  2. Linux で C++ を使用してシステムの日付と時刻を設定する

  3. Linux コマンドを使用して OS とバージョンを確認する方法