我正在尝试在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信号。程序返回所有空格已更正的行,但不会退出。它似乎处于无限循环中。为什么不退出?
答案 0 :(得分:1)
这是由于在POSIX标准中指定了读取系统调用的方式。 http://pubs.opengroup.org/onlinepubs/9699919799/
I / O库中的当收到EOF时,立即等待读取的所有字节 传递到流程而不等待换行符,EOF是 丢弃。因此,如果没有等待的字节(即EOF 发生在一行的开头),字节数为零 从read()返回,表示文件结束指示
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需要在一行的开头,所以你需要先发送换行符。