我已经浏览了有关此K& R示例的网站,答案似乎围绕着'为什么这是一个类型int或什么是EOF?'有点家伙我相信我理解那些。 这是我不了解的结果。我原本以为这个代码需要一个字符,打印它然后等待另一个字符或EOF。
我看到的结果是输入等待直到我按下返回,然后我输入的所有内容都显示出来,等待输入的次数越多。
while循环是否只是循环'直到我用carrage返回结束文本流然后显示putchar(c)一直隐藏在哪里?
代码是:
#include <stdio.h>
/* copy input to output: 1st version */
main()
{
int c;
c = getchar();
while(c != EOF) {
putchar(c);
c = getchar();
}
}
现在,如果我在前一段时间之前潜入putchar(c),我会得到我的预期。我仍然必须输入文本流并按回车键。结果是流的第一个字符,程序退出。
显然,我的情况有很大差距。
感谢您的帮助
答案 0 :(得分:2)
默认情况下,stdin和stdout是缓冲的。这意味着他们可以节省批量的角色并立即发送它们以提高效率。通常情况下,批次会被保存,直到缓冲区中没有空间或者直到流中有换行符或EOF为止。
当您致电getchar()
时,您要求stdin中的字符。假设您键入A
,该字符将保存在缓冲区中,然后系统会等待更多输入。如果键入B
,该字符将进入缓冲区。也许在那之后,你按Enter键,并在缓冲区中放入换行符。但是换行符也会中断缓冲过程,因此对getchar()
的原始调用将返回缓冲区中的第一个字符(A
)。在下一次迭代中,再次调用getchar()
,它会立即返回缓冲区中的下一个字符(B
)。等等。
所以不是你的while循环运行直到你结束这一行,这是第一次调用getchar()
(当缓冲区为空时)正在等待,直到它有一个完整的缓冲区或者它已经看到了换行符。
当您交错输出函数(如putchar()
)时,大多数C运行时库会在您执行向stdout发送数据的操作时“刷新”stdin(反之亦然)。 (目的是确保用户在程序等待输入之前看到提示。)这就是您在添加putchar()
调用时开始看到不同行为的原因。
您可以使用flush()
功能手动刷新缓冲区。您还可以使用setvbuf()
控制标准流使用的缓冲区大小。
正如Han Passant在评论中指出的那样,换行符不会“终止流”。要在stdin上获得EOF,您必须键入Ctrl + D(或者,在某些系统上,按Ctrl + Z)。 EOF也将刷新缓冲区。如果您已将文件或其他程序的输出重定向到stdin,则一旦输入用完,EOF就会发生。
虽然K&amp; R C确实很老,甚至ANSI C今天也不像以前那样常见,但是关于stdin和stdout缓冲的一切在当前标准中甚至在C ++中都是相同的。我认为唯一重要的变化是C标准现在明确地提出了让stdin和stdout引起另一个冲洗的可取性。
答案 1 :(得分:0)
感谢您的回答,并且您所描述的缓冲非常有用且有趣。
显然,我也必须误读/理解,K&amp; R.他们将文本流定义为&#34;。 。 。由零个或多个字符后跟一个新的行字符组成,&#34;我的意思是返回/输入键;结束它,然后允许输出。
另外,我要感谢所有提供有用意见的人。
顺便说一下,我清楚地知道我必须输入^ D来生成EOF,这会终止程序。我感谢你们都是顶级程序员,感谢你们的时间。我想我需要找另一个地方来讨论R&amp; R写的关于这个练习的文字是什么。