防止 C 键盘输入中的 ANSI 转义字符

Preventing ANSI Escape Characters in Keyboard Input in C

我有一个 C 程序,它通过一段代码在 while 循环中(直到按下回车键)从标准输入中读取一些代码来询问用户的姓名。 我确保用户只能输入 32 到 126 之间的 ASCII 值。

问题是当我按下箭头(光标)键,或类似 PAGE_DOWN 或其他... 我最终将 ANSI 转义序列打印到终端([A、[6~ 等])。

这是代码部分。

char name[6];
char c;
uint8_t i = 0;
while ((c = getchar()) != '\n') {
    if (c == 127 || c == 8) {   // Checks if backspace or del is pressed
        i--;
        name[i] = ' ';
    } else if (c >= 32 && c <= 126) {   // Only legal key presses please!
        name[i] = c;
        i++;
    } else {

    }

    if ((c >= 32 && c <= 126) || c == 127 || c == 8) {
        printf_P(PSTR("%c"), c);
    }
}
name[5] = '[=10=]';
move_cursor(15, 18);
printf_P(PSTR("%s"), name);

我当然选择忽略 32 到 126 范围之外的 ASCII 值,那么这是什么原因呢?有任何想法吗?干杯!

这按预期工作。使用 VT100 系列的终端仿真,例如按下光标向上键会向您的应用程序发送以下序列:

<ESC>[A

现在,ESC (0x1b) 被剥离,因为它超出了您的有效范围。但其他字符完全有效。

因此,要同时删除这些,您的程序必须识别终端转义码;一个简单的规则是从转义符中删除所有字符到下一个字母。这不会捕获所有终端转义序列,但对于最常见的它会捕获。

在这里您可以查看list of common terminal control escape sequences

发布的代码不包含某些关键信息。

要使此功能正常工作,代码需要修改与终端通信的'mode'。

正常的 'mode' 是 'cooked',其中击键会回显到终端,而像 'backspace' 这样的击键则由终端驱动程序处理。

要启用所需的功能,'mode' 必须 'raw' 并且 'echo' 必须关闭。