Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.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
Unix(Mac OS)终端不接受Ctrl+D作为EOF_C_Macos_Terminal_Getchar_Stty - Fatal编程技术网

Unix(Mac OS)终端不接受Ctrl+D作为EOF

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;以及系统/垃圾箱/垃

我的问题是: 当我玩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的符号。它起作用了!谢谢!