【发布时间】:2012-01-16 04:55:01
【问题描述】:
我正在寻找一个非常简单的东西:
我想测试是否按下了某个键。 任意键。 如果没有,该程序应继续其业务。 所以它必须是一个“非阻塞”的调用。
我猜这个问题可能相当于检查键盘缓冲区是否有任何内容。
我想这样的函数必须存在于 C 中,但我还不能完全找到它。我发现的所有标准功能都是“阻塞”类型,等待按键被按下后才应答。
注意 - 我打算将它用于 Windows 控制台程序。
【问题讨论】:
我正在寻找一个非常简单的东西:
我想测试是否按下了某个键。 任意键。 如果没有,该程序应继续其业务。 所以它必须是一个“非阻塞”的调用。
我猜这个问题可能相当于检查键盘缓冲区是否有任何内容。
我想这样的函数必须存在于 C 中,但我还不能完全找到它。我发现的所有标准功能都是“阻塞”类型,等待按键被按下后才应答。
注意 - 我打算将它用于 Windows 控制台程序。
【问题讨论】:
在 windows 中,您可以在 conio.h 中使用 '_kbhit()' 这是一个非标准功能,可能在其他平台上不可用。
【讨论】:
我知道这有点旧,但这里有一些可以工作的 Linux 代码
kbhit.h:
#ifndef KBHIT_H__
#define KBHIT_H__
void init_keyboard(void);
void close_keyboard(void);
int kbhit(void);
int readch(void);
#endif
kbhit.c:
#include "kbhit.h"
#include <termios.h>
#include <unistd.h> // for read()
static struct termios initial_settings, new_settings;
static int peek_character = -1;
void init_keyboard(void)
{
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(void)
{
tcsetattr(0, TCSANOW, &initial_settings);
}
int kbhit(void)
{
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(void)
{
char ch;
if(peek_character != -1)
{
ch = peek_character;
peek_character = -1;
return ch;
}
read(0,&ch,1);
return ch;
}
main.c:
#include "kbhit.h"
#define Esc 27
int main(void)
{
init_keyboard(); // for kbhit usage
do {
if(kbhit())
{
ch = tolower(readch());
if(ch == Esc || ch == 'q') break;
if(ch=='s') GetNewTimerValue(TIMER_1);
if(ch=='f') GetNewTimerValue(TIMER_2);
if(ch=='l') {rotateFields();}
}
usleep(330000);
} while(1);
close_keyboard();
return 0;
}
【讨论】: