澄清输入/输出流和输入/输出缓冲区之间的差异

时间:2018-07-21 17:05:39

标签: c++ c

已编辑

输入流和输入缓冲区

据我了解,当按下键盘上的一个键时,字符进入输入流(stdin)并存储在缓冲区中。然后scanf(对于C语言)或cin(对于C ++语言)从缓冲区中提取字符并将其放置在主内存中。

输出流和输出缓冲区

同样,在屏幕上显示字符之前,它们首先要存储在缓冲区中。然后,printf(对于C语言)或cout(对于C ++语言)从缓冲区(当缓冲区已满时)提取字符,并将其发送到输出(stdout)流。

我是对的吗?我已经坚持了好一阵子了,我的逻辑可能有缺陷。

1 个答案:

答案 0 :(得分:1)

旁注:scanf()不是读取输入see more here的功能。


现在是您的问题:在询问C(和C ++)(例如语言)时,您应该停留在该语言提供的抽象概念之内。因此,不要从键盘开始,那不在您的程序之外。

从此处开始:操作系统希望向您提供一些输入。现在,您的C运行时为您的代码提供了输入。 stream 是一个抽象概念,仅表示您可以不断阅读的内容。该流可以被缓冲或不被缓冲,并且如果被缓冲,则存在不同的模式(完全缓冲或行缓冲)可用。您可以配置所有这些。

如果流没有缓冲,这意味着操作系统必须等待,直到您的代码想从输入流中读取。默认情况下,您的标准输入流是行缓冲的,这意味着您的C运行时会立即接受输入并将其放入缓冲区中,直到出现换行为止-您的调用输入函数的代码将从该缓冲区。

从概念上讲,输出会发生相同的情况,反之亦然。例如,如果您的输出流是行缓冲的,则C运行时将填充缓冲区,直到有换行符为止,然后将整行传递给操作系统以进行输出。如果输出没有缓冲,则每个单个字符都会立即传递给操作系统。


免责声明:这仍然做了很多简化,但是从头开始应该足够了。


当您在评论中询问术语“ 缓冲区溢出”时,提到gets() -这是关于您自己的代码中的缓冲区。对于任何读取多个单个值/字符的输入函数,您必须为其提供自己的缓冲区以将结果存储到该缓冲区。使用gets()时,无法告诉函数该缓冲区的大小,因此只要可用输入太大,它就会溢出。这就是gets()定义不明确并同时从C语言中删除的原因。它与C运行时的缓冲区无关,这些缓冲区可能用于I / O流的实现。