Linux下测试按键是否无阻塞按下

Luc*_* S. 4 c++ linux keyboard

我正在搜索如何测试是否按下了某个键。测试不应阻止程序。如果不是太重的话,我可以使用一个小库,但不幸的是 ncurses 的依赖性太大,无法引入。

Luc*_* S. 5

我找到了一个解决方案:

int khbit() const
{
    struct timeval tv;
    fd_set fds;
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    FD_ZERO(&fds);
    FD_SET(STDIN_FILENO, &fds);
    select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
    return FD_ISSET(STDIN_FILENO, &fds);
}

void nonblock(int state) const
{
    struct termios ttystate;
    tcgetattr(STDIN_FILENO, &ttystate);

    if ( state == 1)
    {
        ttystate.c_lflag &= (~ICANON & ~ECHO); //Not display character
        ttystate.c_cc[VMIN] = 1;
    }
    else if (state == 0)
    {
        ttystate.c_lflag |= ICANON;
    }
    tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
}

bool keyState(int key) const //Use ASCII table
{
    bool pressed;
    int i = khbit(); //Alow to read from terminal
    if (i != 0)
    {
        char c = fgetc(stdin);
        if (c == (char) key)
        {
            pressed = true;
        }
        else
        {
            pressed = false;
        }
    }

    return pressed;
}

int main()
{
    nonblock(1);
    int i = 0;
    while (!i)
    {
        if (cmd.keyState(32)) //32 in ASCII table correspond to Space Bar
        {
            i = 1;
        }
    }
    nonblock(0);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

效果很好。谢谢你帮助我。我希望它能帮助别人:)

  • 它可以为非root用户完成工作,谢谢!如果您正在积极等待按下某个键(这不是我的情况,所以我不必这样做),请不要忘记“usleep()”,并且不要忘记恢复回显状态使用后: `ttystate.c_lflag |= ICANON | ECHO;` 在 `nonblock()` 中。 (2认同)