使用 fflush(FILE* stream)

the use of fflush(FILE* stream)

我真的无法理解 :fflush() 函数的用法,我能找到这个函数的一个好的实现吗?我阅读了一些关于它的资源,但我仍然不能很好地掌握它,实际上我想知道这个功能到底做了什么?

引用 C11 标准,第 7.21.5.2 章

int fflush(FILE *stream);

If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush() function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.

因此,基本上,fflush(stream) 调用将强制(即使缓冲区未满)清除与之关联的缓冲区中存在的任何数据特别是 stream 输出文件 (磁盘)。

另外,作为注释,来自第 3 段,同一文档

If stream is a null pointer, the fflush() function performs this flushing action on all streams for which the behavior is defined above.

fflush 当您需要控制写入 stdio FILE 的输出何时实际变得可见时,需要

fflush,因为 stdio 通常缓冲输出并将大块作为一个单元写入。对于在 C 标准库之外不使用与操作系统的任何接口的基本 C 程序,main/only 需要这种控制的时间是在交互式设备上显示输出时 (screen/terminal)并且您想确保它在那里是可见的。但是,在 unix-like/POSIX 系统和其他具有多处理的环境中,您可能还希望确保将数据写出到其他进程可能需要读取的文件或管道中。

了解其功能的最佳方式是标准

7.21.5.2 The fflush function

Synopsis


  1. #include <stdio.h>
    int fflush(FILE *stream);
    

Description

  1. If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.

  2. If stream is a null pointer, the fflush function performs this flushing action on all streams for which the behavior is defined above.

Returns

  1. The fflush function sets the error indicator for the stream and returns EOF if a write error occurs, otherwise it returns zero.

所以基本上库 I/O 函数使用缓冲区,fflush() 将数据从缓冲区移动到 物理 文件,这就是为什么 fflush(stdin) 正如你从上面可以理解的那样是未定义的行为,因为 fflush() 只为 output 流定义。

上面的意思是,对输出流的写操作不会立即执行,它们被缓冲,当你调用fflush()然后它们被刷新到磁盘,你不需要fflush() 始终明确,例如在

fpritnf(stdout, "Example text\n");

打印文本末尾的 "\n" 会自动触发刷新,当您调用 fclose() 或退出程序时也会刷新缓冲区。

您可能还注意到,即使对于输出流,也没有定义行为,除非最近的操作是 输出,输入操作无法刷新。

当您写入 FILE* 使用例如fprintf(甚至 printf 约等于 fprintf(stdout, ...))数据通常存储在缓冲区中。当缓冲区已满时,它刷新(写入)实际输出文件。

如果你想在它满之前将缓冲区的内容写入文件,你可以调用fflush来完成。

流可以被缓冲。这意味着在使用 printffprintf 之类的函数后,您发送的字符不会立即消失。相反,他们等待发送适当的情况。

这可能会产生一些问题,因为有时流最终通过可能需要很长时间。

出于这个原因,有一个命令 fflush(FILE *stream) 强制 流。

在 Unix 系统中,一个程序总是打开 3 个文件描述符:

  1. stdin - 程序输入,缓冲
  2. stdout - 你程序的输出,缓冲
  3. stderr - 错误消息输出,无缓冲

因此,当您使用描述符 stdoutprintf 就是这样做的)并且您希望确保字符出现在正前方时,请使用 fflush.