在Linux上用C++检测按键输入

11

是否有一种简单的方法来检查按键是否被按下,以便我可以在线程中循环执行?最好不要使用库,当然也不能使用ncurses。我在网上找不到任何有效的解决方案。

2个回答

6
尝试这个:-
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>

int main()
{
    struct termios oldSettings, newSettings;

    tcgetattr( fileno( stdin ), &oldSettings );
    newSettings = oldSettings;
    newSettings.c_lflag &= (~ICANON & ~ECHO);
    tcsetattr( fileno( stdin ), TCSANOW, &newSettings );    

    while ( 1 )
    {
        fd_set set;
        struct timeval tv;

        tv.tv_sec = 10;
        tv.tv_usec = 0;

        FD_ZERO( &set );
        FD_SET( fileno( stdin ), &set );

        int res = select( fileno( stdin )+1, &set, NULL, NULL, &tv );

        if( res > 0 )
        {
            char c;
            printf( "Input available\n" );
            read( fileno( stdin ), &c, 1 );
        }
        else if( res < 0 )
        {
            perror( "select error" );
            break;
        }
        else
        {
            printf( "Select timeout\n" );
        }
    }

    tcsetattr( fileno( stdin ), TCSANOW, &oldSettings );
    return 0;
}

这里来:


通常在Windows / OS / 2 / DOS领域中称为kbhit!请记住,您必须获取密钥,否则它将继续报告存在可用的按键。当此指示准备好键时,请调用getch()。 - JimR

5
我发现了一种更简单的方法:
#include <X11/Xlib.h>
#include <iostream>
#include "X11/keysym.h"

/**
 *
 * @param ks  like XK_Shift_L, see /usr/include/X11/keysymdef.h
 * @return
 */
bool key_is_pressed(KeySym ks) {
    Display *dpy = XOpenDisplay(":0");
    char keys_return[32];
    XQueryKeymap(dpy, keys_return);
    KeyCode kc2 = XKeysymToKeycode(dpy, ks);
    bool isPressed = !!(keys_return[kc2 >> 3] & (1 << (kc2 & 7)));
    XCloseDisplay(dpy);
    return isPressed;
}

bool ctrl_is_pressed() {
    return key_is_pressed(XK_Control_L) || key_is_pressed(XK_Control_R);
}

int main(int argc, char **argv) {
    std::cout << ctrl_is_pressed() << std::endl;
    return (0);
};

2
不错,但我认为这只能在X环境下工作(换句话说,在纯tty或Wayland下无法工作,例如)? - domsson
这是什么鬼东西:!!(keys_return[kc2 >> 3] & (1 << (kc2 & 7)))?好吧,这是一些位操作,但这些神奇的数字从哪里来的? - gavrilikhin.d
哦,我明白了。这里有一个简短的解释: - gavrilikhin.d
keys_return 是一个由 32*8 位组成的数组,其中编号为 kc2 的每一位都代表着对应按键的状态。我们的目标是将 kc2 转换为 "二维数组" keys_return 中的坐标。为了实现这个目标,我们首先需要通过除以 8 来获取正确的行数(请记住,每一行有 8 位)。kc2 >> 3kc2 / 8 的结果相同。然后我们获取 "列",即 kc2 % 8,它与 kc2 & 7 相同。但是,由于它是一个位,我们需要将 1 进行移位操作来获取它。 - gavrilikhin.d
因此,等效于 keys_return[kc2 / 8] & (1 << (kc2 % 8)。几乎就像是 arr[n/8][n%8] - gavrilikhin.d

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接