我试图完成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命令行运行程序时,我可以输入文本(“修复这些空格”),然后输入cntl-d来表示EOF。程序返回所有空间的行,但不退出。它似乎处于无限循环中。为什么不退出?
最佳答案
这是由于POSIX标准中指定读取系统调用的方式造成的。
http://pubs.opengroup.org/onlinepubs/9699919799/
当接收到EOF时,所有等待读取的字节将立即
在不等待换行的情况下传递给进程,并且EOF是
丢弃的。因此,如果没有等待的字节(即EOF
出现在一行的开头),字节计数为零
从read()返回,表示文件结束指示getchar
在I/O库中使用面向行的读取系统调用实现。这意味着read()
一次向呼叫者发送一条线路。I/O库将read()返回的字节存储在缓冲区中,如果getchar
,则一次向进程传递一个字节。read()
是面向行的,这一事实导致Cntl-D的不同行为取决于输入是否在行的开头。根据规范,Cntl-D在一条线路的开头立即发出EOF信号。
然而,位于一条直线中间的Cntl-D的作用不同。它将剩余字节发送到进程,并丢弃EOF。这就是为什么需要另一个Cntl-D来向进程发送EOF信号。
关于c - K&R练习1.9-无限循环编程,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33470837/