setvbuf的size参数对于非缓冲流意味着什么?

时间:2018-03-24 10:48:02

标签: c file-io language-lawyer c-standard-library

函数setvbuf()可用于使流无缓冲:

#include <stdio.h>
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
  • size作为mode传递时,_IONBF参数的值是什么意思?

  • 是否会分配缓冲区?

  • 通过0可以吗?

1 个答案:

答案 0 :(得分:0)

C标准的当前版本(C11)说:

  

7.21.5.6 setvbuf功能

     

<强>概要

   #include <stdio.h>
   int setvbuf(FILE * restrict stream,
               char * restrict buf,
               int mode, size_t size);
     

<强>描述

     

setvbuf函数只有在stream指向的流与打开的文件关联之后且在任何其他操作之前(除了setvbuf的失败调用之外)才可以使用在流上执行。参数mode确定如何缓冲流,如下所示:_IOFBF导致输入/输出被完全缓冲; _IOLBF导致输入/输出被行缓冲; _IONBF导致输入/输出无缓冲。如果buf不是空指针,则可以使用它指向的数组而不是setvbuf函数 273 )和参数size分配的缓冲区。指定数组的大小;否则,size可以确定setvbuf函数分配的缓冲区的大小。任何时候数组的内容都是不确定的。

     

<强>返回

     

setvbuf函数在成功时返回零,如果为mode指定了无效值,或者如果请求无法兑现,则返回非零值。

使用条件时态为图书馆作者提供了很多关于如何实施setvbuf()的灵活性。

史蒂夫·萨米特以这种方式论证:

如果将size作为mode传递,则应忽略_IONBF,并且0是合适的值。 (也就是说,如果你传递了0以外的任何数字,它仍然会被忽略,并且不会分配任何内容,但是这个调用会看起来非常误导。)但是我只看了两个不同的手册页&don 39 ; t明确地说出来。

C标准确实允许在所有情况下忽略size,并且对于无缓冲的情况,它会被忽略。

我发现了另一个有意义的替代方案:setvbuf()仍然可以指定流输出函数使用的缓冲区,静态或已分配,只要流函数在其中不保留任何未刷新的输出时他们回来了。例如,printf可以使用此缓冲区来组合其输出并通过块刷新它。 C标准指定未缓冲的流对写入输出流的系统句柄的每个字节使用系统调用。这些是超出标准范围的实施细节。

如果setvbuf()确实尝试分配size字节并失败,则它可能返回非零值而不会使流无缓冲。一种意想不到的行为,仍然符合要求。试试setvbuf(stdout, NULL, _IOFBF, SIZE_MAX);