【问题标题】:How can I distinguish two keystrokes which have similar responses from getch()如何区分与 getch() 具有相似响应的两个击键
【发布时间】:2016-12-07 20:29:44
【问题描述】:

正如我在标题中所说,我如何区分与 getch() 具有相似响应的两个击键。在这个代码块中,K 和左箭头键的 getch() 响应是相同的,所以当我输入大写 k 时 case 75 有效。我该如何解决?我也遇到了这个问题。

     while(1){
            ch1=getch();
        switch( ch2 = getch())
       {
if(ch1 != 0xE0)
{
             default:
            for(i=' ';i<'}';i++)
            {
                if(i == ch2)
                {
                /*SOME STUFF*/
                printf("%c" , iter->x);
                }
 break;
            }


            else
            {
                case 72: printf("UP WAS PRESSED\n");
            break;
           /*Some other stuff*/
            }
        }
    }

【问题讨论】:

  • 不代表可打印字符的键(如左箭头键)没有 ASCII码。
  • 但是当我输入大写 K 时,它不起作用。
  • 不要同时使用 C++ 和 C 来标记您的问题:它们是不同的语言,一种语言的问题解决方案在另一种语言中看起来并不相同。
  • "如何区分两个具有相同 ASCII 码的变量" --> " 如何区分来自getch() 的两个具有相似响应的击键"
  • getch 是一个窗口函数。作为光标控件的键或 Fn 键返回 两个 连续代码。第一个是0224。但是您必须定义int ch2,因为这是来自getch() 的返回值。你还没有显示你的变量类型。

标签: c windows


【解决方案1】:

当按下左箭头等特殊字符时,getch 将首先返回值 0 或 0xE0,然后返回键码(与 ASCII 码不同)。

来自MSDN

_getch_getwch 函数从 控制台而不回显字符。这些功能都不能 用于读取 CTRL+C。读取功能键或箭头键时,每个 函数必须被调用两次;第一次调用返回 0 或 0xE0,并且 第二次调用返回实际的键码。

所以你需要检查一个 0 或 0xE0,它告诉你下一个字符是键码,而不是 ASCII 码。

键码列表:https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx

编辑:

您的if(ch1 != 0xE0) 在任何case 之外,因此会被跳过。此外,当您进入循环时,您总是会调用两次getch。因此,如果您没有获得关键代码,您最终会阅读 2 个常规字符,并且很可能会跳过其中一个。

以单个getch 开始循环。然后检查 0 或 0xE0,如果找到再次调用getch

while (1) {
    int ch = getch();
    int keycode = 0;

    if (ch == 0 || ch == 0xe0) {
        keycode = 1;
        ch = getch();
    }
    switch (ch) {
    ...

【讨论】:

  • 通过 Windows,键盘能否生成单个 ^@ - 空字符,即 ASCII NUL(或者可能是单个 0xE0)?如果是,如何区分另一个字符是否到期?
  • 键码集合中没有列出值0,键码0xE0被标记为“保留”。我没有看到任何关于 null 的提及,所以这似乎是不可能的。
  • 我看到了 Virtual-Key Codes 的链接,但无法找到 a^ctrl z 等的一组键码列表。建议? (找到一个Basic一个)
  • @chux 从我读到的here 中,有一些特定于硬件的扫描码被翻译成虚拟键码。不知道如何阅读扫描码。
  • 感谢您的回答 dbush,我已经尝试过了,但我没有提到问题,我的错。还是行不通。我要编辑我的问题。
猜你喜欢
  • 1970-01-01
  • 2019-10-15
  • 1970-01-01
  • 2012-06-17
  • 2011-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多