读书人

linux程序设计解决思路

发布时间: 2013-11-25 13:22:27 作者: rapoo

linux程序设计
下面是一个类似windows的kbhit()的检测击键动作的函数

#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<termios.h>
#include<term.h>
#include<curses.h>
/*程序开始是标准的程序头和一组对终端设置结构的声明,变量peek_character将用在测试击键动作的代码中。*/
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函数如果按键为q,就退出循环并调用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);
}
/*检测击键动作的函数*/
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;
}

程序第57,58行的
// if(peek_character !=-1)
// return 1;
在程序中的作用是什么?
[解决办法]
引用:
Quote: 引用:

判断peek_character是否被修改过,如果有则直接返回的意思

因为peek_character的初始值是-1所以第一次调用kbhit函数时是不会执行这两句的。然后如果键入了一个值peek_character被修改了,但是接下来肯定要执行readch函数因为被修改了所以肯定不会等于-1,然后执行
if(peek_character!=-1)
{
ch=peek_character;
peek_character=-1;
return ch;
}
就把peek_character重置了,所以每次运行到kbhit时肯定不会这些那两条语句啊。

多线程啊,在这条线程还没有重置peek_character的情况下,另一条线程进入了这个函数那么就可以执行啦。

读书人网 >C语言

热点推荐