【问题标题】:Is there a way to detect if a key has been pressed?有没有办法检测是否按下了某个键?
【发布时间】:2014-04-05 15:23:05
【问题描述】:

我正在 Windows 计算机上用 cygwin 编译和执行我的程序。我在 C 方面非常缺乏经验,但我想要一种方法来检测是否已按下某个键而不提示用户(例如我)。我的具有理想功能的伪代码如下所示。

char ch;
while(1){
    if(KeyBeenPressed()){
    //a key has been pressed before getting here
        ch=getKeyPressed();
        if(ch=='0'){
            printf("you have pressed 0");
        }
        else{
            printf("you did't press key 0");
        }
    }

//do other stuff
} 

我自己在搜索网络后尝试解决这个问题如下所示。

#include <stdio.h>
#include <conio.h>
char ch;
void main(){
    while(1){
        if(kbhit()){ //kbhit is 1 if a key has been pressed
            ch=getch();
            printf("pressed key was: %c", ch);
        }
    }
}

此代码的一个问题是找不到 conio.h 文件(我还没有找到任何其他方法来解决这个问题)。显然 gcc 编译器无法处理 conio.h(我已将链接附加到它的位置)。 http://www.programmingsimplified.com/c/conio.h

所以我想知道你们中是否有人知道一种方法来检测是否在 C 中按下了一个键,我还想最好在一个字符中检索按下的键(我计划在这个应用程序中使用 0-9) .重要的是程序不能等到按键被按下。

感谢任何可以解决此问题的建议! 最好的祝福 亨里克

【问题讨论】:

标签: c windows keyboard keypress detection


【解决方案1】:

大部分Dos、Windows 3.x或win32平台提供conio.h文件,但unix或linux os 不正常提供这个文件。如果您使用 unix 或 linux Os ,您必须自己在互联网上下载。希望我的回答对你有用。

【讨论】:

    【解决方案2】:

    我对@9​​87654321@ 使用以下函数。它在 Ubuntu 的 g++ 编译器上运行良好。

    #include <termios.h>
    #include <unistd.h>
    #include <fcntl.h>
    int kbhit(void)
    {
      struct termios oldt, newt;
      int ch;
      int oldf;
    
      tcgetattr(STDIN_FILENO, &oldt);
      newt = oldt;
      newt.c_lflag &= ~(ICANON | ECHO);
      tcsetattr(STDIN_FILENO, TCSANOW, &newt);
      oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
      fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
    
      ch = getchar();
    
      tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
      fcntl(STDIN_FILENO, F_SETFL, oldf);
    
      if(ch != EOF)
      {
        ungetc(ch, stdin);
        return 1;
      }
    
      return 0;
    }
    

    【讨论】:

    • 这段代码真的很好用。但我想知道 tcgetattr(STDIN_FILENO, &oldt); 发生了什么到 fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);我会尝试自己找到它,但如果您有时间,我将不胜感激。谢谢您的帮助! //亨利克
    • tcgetattr(STDIN_FILENO, &oldt);蝾螈 = 旧的; newt.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &newt); oldf = fcntl(STDIN_FILENO, F_GETFL, 0); fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
    • 在您询问后,我试图找到这些陈述的完整含义。通常,getchar() 是阻塞的,即等待用户输入并在用户按下“ENTER”键后继续。因此 tcgetattr 和 tcsetattr 用于从终端获取输入,而无需按“ENTER”键。 tcgetattr 获取 oldt 中终端的当前设置。 tecsetattr 设置终端的新设置。 fcntl 用于从标准输入获取非阻塞输入。读取字符后,使用 tcsetattr 和 fnctl 恢复之前的设置。
    • 好的,我希望我现在已经将答案标记为已接受(我之前不知道有这样的事情:P)谢谢您的解释!
    猜你喜欢
    • 2017-09-03
    • 1970-01-01
    • 2011-10-08
    • 2014-07-13
    • 2016-03-27
    • 2016-10-31
    • 1970-01-01
    • 1970-01-01
    • 2021-08-10
    相关资源
    最近更新 更多