【发布时间】:2017-06-26 20:08:52
【问题描述】:
我正在尝试用 C 语言编写一个示例程序,它可以逐个字符地读取用户输入的内容,而无需用户按 Enter。我使用了here 看到的代码,它工作得很好,只是有一个小问题。我想在用户按下回车时处理所有用户的输入,而当我使用system(/bin/stty raw); 时,程序无法再检测到它。如:
int n, i;
char buffer[50];
system ("/bin/stty raw");
for(i=0; i<30 ; i++) {
buffer[i] = getchar();
printf("%d\n", buffer[i] == '\n'); //this prints 0 when I press enter
if(buffer[i] == '\n'){
break;
}
}
printf("%s\n",buffer);
system ("/bin/stty cooked");
有没有办法检测用户在执行此操作时是否按下了回车键?
我实际上想要做的是在用户按下回车之前阅读用户的输入,但在他们这样做时做一些事情。我想到的另一种方法是,如果我不逐个字符地读取它,而是使用例如fgets(buffer, 255, stdin);,有没有办法在用户按下回车之前读取 stdin 的缓冲区?我想为此使用 Enter 键,因此不能在另一个字符上终止用户输入,例如使用 while((c=getchar())!= '.'){},使用 here 不是一个选项。
【问题讨论】:
-
对于
raw,您是否打开了icrnl和/或inlcr?这些与输入上的 CR 到 NL(\r到\n)映射有关。尝试:system("/bin/stty -a");在你的代码中——甚至可能两次,一次在打开raw之前,一次在打开之后。或者,换句话说,在原始模式下工作时,您很有可能需要捕获\r,而不是\n。 -
这是所有代码。真的,我只漏掉了
int main()和return 0; -
如果你是在向我讲话,Luke,那么我并不是说你应该创建更多的 MCVE。我告诉你,
stty raw命令正在更改终端中的许多设置,其中一些与 CR (\r) 到 NL (\n) 的转换有关,反之亦然。我还建议您可以尝试在执行stty raw之前和之后查找设置——这将帮助您确定发生了什么变化。此外,正如答案中所指出的,您应该考虑使用 POSIX<termios.h>标头和相关功能来更直接地管理终端设置。 -
您可能会发现在程序篡改终端控件之前捕获
stty -g的输出很有用(使用popen()),然后您可以使用该字符串将终端重置为确切状态它在stty -g运行时。 -
另请注意,
getchar返回int而不是char是有原因的,并且您在此处导致的从int到char的隐式缩小转换会丢弃信息...弄清楚这些信息是什么,因为它可能对您解决尚未注意到的错误有用。
标签: c