Unix(Mac OS)终端不接受Ctrl+D作为EOF
我的问题是: 当我玩getchar行为时,我发现我的终端macOS Mohave版本10.14.6 18G87不支持Ctrl+D作为EOF 我是如何解决这个问题的: 下面附加了带有getchar的代码,如果输入字符不是空的,则基本上该代码是echo getchar,否则,对于多个连续的空字符,它只输出一个空字符。 代码本身可以工作,但在终端中运行它时,终端不会将Ctrl+D作为EOF,因此代码永远不会终止。 我确信这是因为我错误地使用了system/bin/stty-raw;以及系统/垃圾箱/垃圾箱,然而,我不知道如何修复它Unix(Mac OS)终端不接受Ctrl+D作为EOF,c,macos,terminal,getchar,stty,C,Macos,Terminal,Getchar,Stty,我的问题是: 当我玩getchar行为时,我发现我的终端macOS Mohave版本10.14.6 18G87不支持Ctrl+D作为EOF 我是如何解决这个问题的: 下面附加了带有getchar的代码,如果输入字符不是空的,则基本上该代码是echo getchar,否则,对于多个连续的空字符,它只输出一个空字符。 代码本身可以工作,但在终端中运行它时,终端不会将Ctrl+D作为EOF,因此代码永远不会终止。 我确信这是因为我错误地使用了system/bin/stty-raw;以及系统/垃圾箱/垃
/* K&R C Exercise 1-9. Write a program to copy its input to its output,
* replacing each string of one or more blanks by a single blank.*/
#include <stdio.h>
#include <stdlib.h>
int main(void){
int ch;
int prev = -1;
/* if you are in a UNIX like environment
* the ICANON flag is enabled by default, so input is buffered until the next '\n' or EOF
* https://stackoverflow.com/a/1799024/5450745
* */
system ("/bin/stty raw");
while ((ch=getchar())!= EOF){
if (ch != ' ' ){
if (prev == ' '){
putchar(prev);
putchar(ch);
}
else{
putchar(ch);
}
prev = ch;
}
else{
prev = ch;
continue;
}
}
/* use system call to set terminal behaviour to more normal behaviour */
system ("/bin/stty cooked");
return 0;
}
我选中了stty,但是它确实将EOF配置为Ctrl+D。但是,现在,如果我按Ctrl+D,它只会将终端从一个窗口拆分为两个窗口
我可以做些什么来允许再次启用EOF
谢谢 这段代码在运行macOS Catalina 10.15的Mac电脑上适用。我希望它在任何你可以使用的类似Unix的系统上,包括旧版本的macOS上,都能起到基本相同的作用。它通过将ch与标准C中的“\004”八进制4-可写的许多其他方式进行比较来识别control-D,包括键入和终止循环时仅检测到4
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int ch;
int prev = -1;
/* if you are in a UNIX like environment
* the ICANON flag is enabled by default, so input is buffered until the next '\n' or EOF
* https://stackoverflow.com/a/1799024/5450745
* */
system("/bin/stty raw");
while ((ch = getchar()) != EOF && ch != '\004')
{
if (ch != ' ')
{
if (prev == ' ')
{
putchar(prev);
putchar(ch);
}
else
{
putchar(ch);
}
prev = ch;
}
else
{
prev = ch;
continue;
}
}
/* use system call to set terminal behaviour to more normal behaviour */
system("/bin/stty cooked");
return 0;
}
当然,输出显示有点奇怪——例如,键入return不会将光标移动到下一行。但是对ch='\004'的测试在键入control-D时会检测到。空格消除码也起作用
使用stty cbreak而不是stty raw将启用中断,但通过control-D的EOF仍然被禁用。投票迁移到,因为这不是编程问题,而是终端配置。raw模式输入不支持任何特殊字符-无EOF、无擦除、无中断、无退出、无终止,等等,也许是Sty cbreak——我还没有做过实验,我也不确定。请注意,此时也不能擦除字符。一个关键的stty标志是icanon/-icanon。你的问题与MacOS无关,一切都与你的stty呼叫有关。如果你想按照作者的意图做这个练习,就不要再打stty电话了。如果你想在输入字符时立即看到它们——我记得我第一次在K&R中做了类似的练习——那么是的,你必须修补tty模式,但你也必须自己检查control-D。最简单的方法是将循环更改为while ch=getchar!=EOF&&ch!=4.您实际上是在按ctrl+d而不是command+d吗?因为command+d是在MacOS终端中拆分窗口的默认快捷方式。您可以在ch=getchar!=EOF&&ch!='\004'{由于如果stty命令起作用,将不会检测到EOF,您可以将其简化为while ch=getchar!=\004'{。值'\004'`相当于'\4'和'\x04'以及4也是control-D的符号。它起作用了!谢谢!