C中的缓冲和非缓冲输入
有没有办法弄清楚input
是buffered
还是非unbuffered
(除了手册页。)? 我们不能通过查看函数的名称来弄清楚吗? 也适用于echoing
和非nonechoing...
有关快速参考,哪里可以找到具有Buffered
, Unbuffered
, echoing
和非nonechoing
输入详细信息的列表?
用于从FILE
读取的所有 stdio.h
函数可能表现出“缓冲”或“无缓冲”行为,以及“回显”或“非回显”行为。 控制这些内容的不是您使用的function,而是流和/或其底层文件描述符上的设置。
-
标准库函数
setvbuf
可用于启用或禁用C库对输入(和输出)的缓冲。 这对操作系统的缓冲没有影响。 有三种可能的模式:“完全缓冲”(以大量块读取或写入); “line buffered”(缓冲区直到'\n'
字符被读取或写入,但不超过该字符); 和“无缓冲”(所有读取和写入立即进入操作系统)。 -
新
FILE
对象(包括stdin
和friends)的默认缓冲是实现定义的。 Unixy C库通常将所有FILE
默认为完全缓冲,但有两个例外。stderr
默认为无缓冲。 对于任何其他FILE
,如果在第一次实际读取或写入时尚未使用setvbuf
,并且对于基础文件描述符isatty
为true,则FILE
将变为行缓冲。 -
一些C库提供扩展function,例如Linux和Solaris上的
__flbf
和朋友,用于读回由setvbuf
控制的一些设置。 请记住,如上所述,缓冲模式可以在第一次实际读取或写入时更改,如果尚未明确设置的话。
如果输入来自文件,则setvbuf
是您拥有的唯一旋钮。 如果输入来自某种通信渠道,则可能还有其他旋钮:
-
在符合POSIX标准的系统上(读取“Windows以外的所有内容”),程序可以请求终端输入的几种不同模式中的任何一种。 其中,最重要的区别在于“规范”和“非规范” 。 规范模式的终端表现出缓冲和回声。 (如果没有使用
setvbuf
来禁用它,则此缓冲与C库可能执行的缓冲是分开的。)非规范模式允许您单独切换缓冲和回显。 低级POSIX终端接口广泛,复杂,允许您读取和写入所有这些设置。 -
如果您认为要将终端设置为非规范模式,那么在针对低级POSIX API编写一堆代码之前,您应首先考虑
readline
或ncurses
库是否会让您的生活更轻松。 -
如果你正在阅读一个管道,那么无论是谁写的,你都会受到它的支配; 你无法控制你得到的块的大小。
-
如果你正在读取套接字,你可以通过小心使用
recvmsg
来控制你获得的块的大小,但是没有保证。 -
我不知道它在Windows上是怎么回事。
ISO / IEC 9899-1999 C99语言标准
5.1.2.3程序执行
…
5)交互设备的输入和输出动态应按照7.19.3的规定进行。 这些要求的目的是尽快出现无缓冲或行缓冲输出,以确保在程序等待输入之前实际出现提示消息。 …
7.19.3文件
…
3)当流是无缓冲的时,字符应尽快从源或目的地出现。 否则,可以将字符作为块累积并发送到主机环境或从主机环境发送。 当流被完全缓冲时,当填充缓冲区时,字符旨在作为块传输到主机环境或从主机环境传输。 当流被行缓冲时,当遇到换行符时,字符将作为块传输到主机环境或从主机环境传输。 此外,当填充缓冲区,在无缓冲流上请求输入时,或者在需要从主机环境传输字符的行缓冲流上请求输入时,字符旨在作为块传输到主机环境。 。 对这些特性的支持是实现定义的,可能会受到setbuf和setvbuf函数的影响。 …
7)在程序启动时,预定义了三个文本流,无需明确打开 – 标准输入(用于读取常规输入),标准输出(用于写入常规输出)和标准错误(用于写入诊断输出)。 最初打开时,标准错误流未完全缓冲; 当且仅当可以确定流不参考交互设备时,标准输入和标准输出流是完全缓冲的。
您可以使用setvbuf()
将缓冲区与文件(包括stdin
setvbuf()
。 您可以将缓冲模式更改为完整,行或无。