防止 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) 被剥离,因为它超出了您的有效范围。但其他字符完全有效。
因此,要同时删除这些,您的程序必须识别终端转义码;一个简单的规则是从转义符中删除所有字符到下一个字母。这不会捕获所有终端转义序列,但对于最常见的它会捕获。
发布的代码不包含某些关键信息。
要使此功能正常工作,代码需要修改与终端通信的'mode'。
正常的 'mode' 是 'cooked',其中击键会回显到终端,而像 'backspace' 这样的击键则由终端驱动程序处理。
要启用所需的功能,'mode' 必须 'raw' 并且 'echo' 必须关闭。
我有一个 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) 被剥离,因为它超出了您的有效范围。但其他字符完全有效。
因此,要同时删除这些,您的程序必须识别终端转义码;一个简单的规则是从转义符中删除所有字符到下一个字母。这不会捕获所有终端转义序列,但对于最常见的它会捕获。
发布的代码不包含某些关键信息。
要使此功能正常工作,代码需要修改与终端通信的'mode'。
正常的 'mode' 是 'cooked',其中击键会回显到终端,而像 'backspace' 这样的击键则由终端驱动程序处理。
要启用所需的功能,'mode' 必须 'raw' 并且 'echo' 必须关闭。