4

我正在用 c/c++ 实现一个密钥阅读器程序。我正在使用Linux。我知道无缓冲的 getchar 函数将返回很少的键数据值。对于所有 ASCII 键(az、AZ、1-9、标点符号、回车、制表符和 ESC),getchar() 将返回一个值。对于其他键,例如方向键,会读取 ESC 键,但是当再次调用 getchar() 时,它会得到另一个值(A、B、C 或 D)。

A = 65

乙 = 66

向上箭头 = 27 91 65

F5 = 27 91 49 53 126

ESC = 27

完整的桌子在这里

有没有办法检查是否有更多的字符要读取或者是否只有一个字符?当一个键被读取并且它的第一个值是 ESC 我不知道它是一个以 ESC 开头的功能键还是只是 ESC 键。

#include <stdlib.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <iostream>
#include <string>
#include <termios.h>
#include <unistd.h>

using namespace std;

int main(int argc, char *argv[]) {

    int ch[5];
    int i;
    struct termios term;

    tcgetattr( STDIN_FILENO, &term );
    term.c_lflag &= ~( ICANON | ECHO );
    tcsetattr( STDIN_FILENO, TCSANOW, &term );

    ch[0] = getchar();

    // If ch[0] = 27 and there is more data in the buffer
    // printf("You pressed a function key");
    // Else
    // printf("You pressed ESC");

    return 0;   

}
4

3 回答 3

0

获得第一个 ESC 字符后,无需等待即可读取其他字符(例如通过在 termios 结构中设置 c_cc[VMIN] = 0 和 c_cc[VTIME] = 0),然后如果您找到的字符与功能键模式不匹配,您将已读取的字符插入要读回的缓冲区中。然后,在下一次获取时,您首先返回缓冲的字符(如果有)。

于 2014-10-15T11:05:13.660 回答
0

您可以在逃脱时将 stdio 标记为非阻塞,然后尽可能多地阅读。您需要包含 <fcntl.h>

if (ch[0] == 27) {
    int flags = fcntl(STDIN_FILENO, F_GETFL, 0);
    fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK);
    for (;;) {
        int c = getchar();
        if (c == EOF)
            break;
        printf("%u ", c);
    }
    fcntl(STDIN_FILENO, F_SETFL, flags);
    puts("\n");
}

两个键相继出现仍然存在问题,因为循环将读取直到没有更多可用数据。

于 2013-05-22T13:28:42.093 回答
-1

在循环中添加 getchar() 并在输入的键为 ENTER 时退出循环。例如:

char ch[5];
int i=0;
while(1)
{
   ch[i] = getchar();
   if('\n'==ch[i])
   {
     break;
   }
   i++;
   if(i==5)
   {
     break;
   }

}
于 2013-05-22T06:27:22.707 回答