K& R练习1.9 - 无限循环编程

时间:2015-11-02 04:36:04

标签: c

我正在尝试在K& R中完成练习1-9,我想出了这个:

#include <stdio.h>

/* this program will trim each group of spaces down to a single space */
int main()
{
    int c, lastCharblank;
    lastCharblank = 0;

    while ((c = getchar()) != EOF) {
        if (c != ' ' || !lastCharblank)
            putchar(c);

        lastCharblank = (c == ' ');
    }

    putchar('\n');

    return 0;
}

在通过bash命令行运行程序时,我能够输入文本(&#34;修复这些空格&#34;)然后输入cntl-d来发出EOF信号。程序返回所有空格已更正的行,但不会退出。它似乎处于无限循环中。为什么不退出?

2 个答案:

答案 0 :(得分:1)

这是由于在POSIX标准中指定了读取系统调用的方式。 http://pubs.opengroup.org/onlinepubs/9699919799/

  

当收到EOF时,立即等待读取的所有字节   传递到流程而不等待换行符,EOF是   丢弃。因此,如果没有等待的字节(即EOF   发生在一行的开头),字节数为零   从read()返回,表示文件结束指示

I / O库中的

getchar是使用面向行的读取系统调用实现的。这意味着read()一次向呼叫者发送一行。 I / O库将read()返回的字节存储在缓冲区中,如果是getchar,则一次向进程传递一个字节。

read()面向行的事实导致Cntl-D的不同行为取决于输入是否在行的开头。根据规范,线路开头的Cntl-D立即发出EOF信号。

但是,行中间的Cntl-D行为不同。它将剩余的字节发送到进程,并丢弃EOF。这就是为什么需要另一个Cntl-D来向该过程发出EOF信号的原因。

答案 1 :(得分:0)

我似乎在使用一个平台,CTRL-D不是发送EOF的正确密钥绑定。例如。在Windows上,它通常是CTRL-Z。

编辑:是的,正如其他人已经说过的那样,EOF需要在一行的开头,所以你需要先发送换行符。