C中的非阻塞“按键”测试

时间:2011-12-08 19:14:05

标签: c keyboard

我正在寻找一个非常简单的事情:

我想测试是否按下了某个键。任何关键。 如果没有,该计划应继续其业务。 所以它必须是一个“非阻塞”的呼叫。

我想这个问题可能等同于检查键盘缓冲区是否有任何内容。

我想这样的功能必须存在于C中,但我还是找不到它。我找到的所有标准功能都是“阻塞”类型,等待在回答之前按下一个键。

请注意,我打算将它用于Windows控制台程序。

2 个答案:

答案 0 :(得分:4)

在Windows中,您可以在conio.h中使用'_kbhit()' 它是一种非标准功能,可能无法在其他平台上使用。

答案 1 :(得分:1)

我知道这有点老了,但这是一些可以工作的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;     
}