mmxingye

导航

09 | linux键盘敲击(linux下的 kbhit 函数)

Linux系统中没有与其直接等同的函数。但UNIX程序员对此并不在意,因为在UNIX下编写的程序几乎不或很少忙于等待某个事件的发生。由于kbhit函数的主要用途就是等待某个击键动作的发生,所以在UNIX和Linux系统上未实现类似的函数。

但当需要移植MS_DOS下的程序时,如果能够模拟kbhit函数所完成的功能将会很方便。你可以用非标准输入模式来实现它。. 非标准输入模式

#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <term.h>
#include <curses.h>
#include <unistd.h>
static struct termios initial_settings, new_settings;
static int peek_character = -1;
void init_keyboard(); 
void close_keyboard() ;
int kbhit() ;
int readch();
// main函数首先调用init_keyboard函数来配置终端,然后每隔-秒循环调用一次kbhit函数。如果按键为g,就退出循环并调用close_keyboard函数恢复终端为标准模式,最后退出程序。

int main()
{
	int ch =0;
	init_keyboard() ;           //首先配置终端
	while(ch!= 'q') {
		printf ("looping\n") ;
		sleep(1);
		if (kbhit()) {
			ch= readch() ;
			printf("you hit %c\n",ch) ;
		}
		close_keyboard();		//恢复终端配置
		exit(0) ;
	}
}
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) ;
}
//下面就是检测是否有击键动作的kbhit函数:
int kbhit ()
{
	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;
}

//按键对应的字符由下-一个函数readch读取,它会将变量peek_ character重置为-1以进入下一次循环。

int readch()
{
	char ch;
	if(peek_character != -1) {
		ch = peek_character;
		peek_character = -1;
		return ch;
	}
	read(0,&ch,1) ;
	return ch;
}

posted on 2022-06-01 20:21  独立树  阅读(953)  评论(0编辑  收藏  举报