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