Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在Linux上测试是否在不阻塞的情况下按键_C++_Linux_Keyboard - Fatal编程技术网

C++ 在Linux上测试是否在不阻塞的情况下按键

C++ 在Linux上测试是否在不阻塞的情况下按键,c++,linux,keyboard,C++,Linux,Keyboard,我正在搜索如何测试按键是否按下。测试不应该阻止程序。如果不太重的话,我可以用一个小图书馆,但不幸的是,ncurses的依赖性太大了,我不知道你到底在找什么 我最近在这里对“原始”输入设备节点进行了概念验证:。这个例子是关于鼠标的,但是Linux内核统一了输入设备,所以键盘也差不多 这里您只需要UNIX权限来打开/读取设备文件(如果您的部署风格更方便的话,您可以从-/etc树中创建它们) 该示例显示事件的完全异步处理 我使用了到XTest(libxtst)的绑定(实际上是为了发送击键);我想这可

我正在搜索如何测试按键是否按下。测试不应该阻止程序。如果不太重的话,我可以用一个小图书馆,但不幸的是,ncurses的依赖性太大了,我不知道你到底在找什么

  • 我最近在这里对“原始”输入设备节点进行了概念验证:。这个例子是关于鼠标的,但是Linux内核统一了输入设备,所以键盘也差不多

    这里您只需要UNIX权限来打开/读取设备文件(如果您的部署风格更方便的话,您可以从-/etc树中创建它们)

    该示例显示事件的完全异步处理

  • 我使用了到XTest(
    libxtst
    )的绑定(实际上是为了发送击键);我想这可能包含您需要的功能

  • 然后是XInput(据我所知),它构成了提取我在第一个选项中描述的“原始”输入设备流的XOrg方法

我找到了一个解决方案:

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

它工作得很好。谢谢你帮助我。我希望它能帮助某些人:)

这是离题的,因为您要求我们提供代码/教程“我不能使用ncurse”。为什么?无论如何,你可以看看他们的来源,了解他们实际上是如何做的。@πάνταῥεῖ 可能是因为它太重了吧?从这个问题上来说:“如果它们不太重的话,我可以使用小lib”,这并不是离题。这类问题正是大多数人使用这个网站的目的。(我无法想象这不是一个重复,虽然…)这个问题不是离题的。就目前而言,这只是一个懒散地问的问题,不符合好问题的指导原则。它为不是root的人做了这项工作,谢谢!如果您正在积极等待按键(这不是我的情况,所以我不必这么做),请不要忘记在使用后恢复回显状态:
ttystate.c_lflag |=ICANON | echo
nonblock()
中。太棒了!非常感谢你。Shiublu关于重新启用echo是正确的。我想补充的是,你需要这些include#include#include#include#我还想补充的是,函数不能是常量,因为它们修改了环境(g++5.4在它上失败)。我更喜欢这个修改过的keystate函数,它只是告诉您按下了哪个键,而不是测试是否按下了特定的键:bool keystate(int&key){IF(khbit()==0)return false;key=fgetc(stdin);return true;}