Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中防止键盘输入中的ANSI转义字符_C_String_User Input_Stdin_Ansi - Fatal编程技术网

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

在C中防止键盘输入中的ANSI转义字符,c,string,user-input,stdin,ansi,C,String,User Input,Stdin,Ansi,我有一个C程序,要求用户输入他们的名字,并在while循环中读取stdin的代码(直到按下enter)。 我确保用户只能输入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)

我有一个C程序,要求用户输入他们的名字,并在while循环中读取stdin的代码(直到按下enter)。 我确保用户只能输入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] = '\0';
move_cursor(15, 18);
printf_P(PSTR("%s"), name);
字符名[6];
字符c;
uint8_t i=0;
而((c=getchar())!='\n'){
如果(c==127 | | c==8){//检查是否按下了backspace或del
我--;
名称[i]='';

}否则,如果(c>=32&&c=32&&c,这将按预期工作。对于VT100系列的终端模拟,例如,按下向上光标键将向应用程序发送以下序列:

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

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


在这里,您可以查看发布的代码不包含某些关键信息

要使此功能正常工作,代码需要修改与终端通信的“模式”

正常的“模式”是“煮熟”模式,其中按键回显到终端,像“退格”这样的按键由终端驱动程序处理


要启用所需的功能,“模式”必须是“原始”且“回声”必须关闭。

请提供MCVE@CIsForCookies谢谢!我已添加了相应的剪接,但我正在为侦听串行com端口的终端编写代码,因此对于常规标准输出,代码有点不同。如果是分配,请不要使用用户终端。如果需要更好的UX对于生产程序来说,使用GNU readline或类似的库而不是stdio。在其他新闻中,不要使用像126、8或32这样的神奇数字。C有字符文字,请使用它们。别担心,分配不会标记代码质量。只看实现的功能。看,我们正在AVR微控制器上制作snake游戏,并且LED矩阵。在用户终端之间来回发送信息对于显示其他信息很有用。我来试一试!当你说“这不会捕获所有终端转义序列”时,这是因为一些长度不同吗?例如,大多数是“[X”形式,但向下翻页是“[6~”?@TristanBatchler不同的长度是没有问题的,因为你把所有的东西都去掉,直到下一个字母(不是数字!),但是如果在序列的结尾之前有字母,它将不会被充分剥离。但是你很少会遇到这些字母中的任何一个。太棒了!我刚刚开始尝试你的建议,它看起来已经很好了。谢谢你的回答!@ctx:Make that“删除(忽略)从转义到下一个大写字母
A
-
Z
、小写字母
A
-
Z
~
”的所有字符,基本上涵盖POSIXy系统中的键盘输入。