【C++】linux下监听键盘事件(按键后非阻塞读取,不用Enter)

#include <termio.h>
#include <stdio.h>

int scanKeyboard()
{
    int input;
    struct termios new_settings;
    struct termios stored_settings;
    tcgetattr(0,&stored_settings);
    new_settings = stored_settings;
    new_settings.c_lflag &= (~ICANON);
    new_settings.c_cc[VTIME] = 0;
    tcgetattr(0,&stored_settings);
    new_settings.c_cc[VMIN] = 1;
    tcsetattr(0,TCSANOW,&new_settings);
     
    in = getchar();
     
    tcsetattr(0,TCSANOW,&stored_settings);
    return input;
}

//返回该键的ASCII码值,不需回车

 

解析:

ICANON
Enable canonical mode. This enables the special characters EOF, EOL, EOL2, ERASE, KILL, LNEXT, REPRINT, STATUS, and WERASE, and buffers by lines.

可以看出 ICNAON 标志位启用了整行缓存。

所以,new_settings.c_lflag &= (~ICANON);这句屏蔽整行缓存。那就只能单个了。

通过tcsetattr函数设置terminal的属性来控制需不需要回车来结束输入。


注:通过while循环读取键盘效率很低,参考使用异步事件或者多线程技术。单线程为阻塞式的

  

【原文】https://blog.csdn.net/alangdangjia/article/details/27697721

在windows下有个键盘测试函数,int kbhit(void)。使用该函数需要包含头文件conio.h。执行时,kbhit测试是否有键盘按键按下,若有则返回非零值,否则返回零。

在Unix/Linux下,并没有提供这个函数。在linux下开发控制台程序时,有时会遇到检测键盘是否有被按下的情况,这时就需要自己编写 kbhit() 实现的程序了。

#include <stdio.h>
#include <termios.h>
 
static struct termios initial_settings, new_settings;
static int peek_character = -1;

void init_keyboard(void);
void close_keyboard(void);
int kbhit(void);
int readch(void); 

void init_keyboard()
{
	tcgetattr(0,&initial_settings);
	new_settings = initial_settings;
	new_settings.c_lflag |= ICANON;
	new_settings.c_lflag |= ECHO;
	new_settings.c_lflag |= ISIG;
	new_settings.c_cc[VMIN] = 1;
	new_settings.c_cc[VTIME] = 0;
	tcsetattr(0, TCSANOW, &new_settings);
}
 
void close_keyboard()
{
	tcsetattr(0, TCSANOW, &initial_settings);
}
 
int kbhit()
{
	unsigned char ch;
	int nread;
 
	if (peek_character != -1) return 1;
	new_settings.c_cc[VMIN]=0;
	tcsetattr(0, TCSANOW, &new_settings);
	nread = read(0,&ch,1);
	new_settings.c_cc[VMIN]=1;
	tcsetattr(0, TCSANOW, &new_settings);
	if(nread == 1) 
	{
		peek_character = ch;
		return 1;
	}
	return 0;
}
 
int readch()
{
	char ch;
 
	if(peek_character != -1) 
	{
		ch = peek_character;
		peek_character = -1;
		return ch;
	}
	read(0,&ch,1);
	return ch;
}
 
int main()
{
	init_keyboard();
	while(1)
	{
		kbhit();
		printf("
%d
", readch());
	}
	close_keyboard();
	return 0;
}

 

linux termios 结构:

https://blog.csdn.net/querdaizhi/article/details/7436722

原文地址:https://www.cnblogs.com/SchrodingerDoggy/p/14072739.html