为什么我需要刷新I / O流才能获得正确的结果?

时间:2010-02-09 16:24:34

标签: c iostream

为什么以下代码不起作用?我的意思是,它在控制台输出上显示各种奇怪的字符。

#include <stdio.h>
char mybuffer[80];
int main()
{
    FILE * pFile;
    pFile = fopen ("example.txt","r+");
    if (pFile == NULL) perror ("Error opening file");

    else {
        fputs ("test",pFile);

        fgets (mybuffer,80,pFile);
        puts (mybuffer);
        fclose (pFile);
        return 0;
    }
}

但是,下面的代码效果很好。

#include <stdio.h>
char mybuffer[80];
int main()
{
    FILE * pFile;
    pFile = fopen ("example.txt","r+");
    if (pFile == NULL) perror ("Error opening file");

    else {
        fputs ("test",pFile);
        fflush (pFile);    
        fgets (mybuffer,80,pFile);
        puts (mybuffer);
        fclose (pFile);
        return 0;
    }
}

为什么我需要刷新流才能获得正确的结果?

3 个答案:

答案 0 :(得分:12)

因为标准是这样说的(§7.19.5.3/ 5):

  

使用更新模式打开文件时   ('+'作为第二个或第三个字符   在上面的模式参数列表中   值),输入和输出都可以   在关联的流上执行。   但是,输出不应直接输出   然后输入没有   干预fflush的呼吁   功能或文件定位   功能(fseek,fsetpos或倒带),   输入不得直接输入   然后输出没有   干预调用文件定位   功能,除非输入操作   遇到文件结束。

这是有原因的:输出和输入通常是单独缓冲的。当有刷新或搜索时,它会将缓冲区与文件同步,但否则会让它们失去同步。这样可以提高性能(例如,当您执行读取操作时,无需检查您读取的位置是否已写入,因为数据已读入缓冲区)。

答案 1 :(得分:7)

使用具有读/写模式的文件时,必须在不同的i / o操作之前调用fseek / fflush。

why fseek or fflush is always required...

上查看此答案

答案 2 :(得分:2)

因为C文件io使用缓冲区。这只是在你刷新它,写一个/ n字符或填满缓冲区时写入磁盘。

因此,在第一种情况下,当您从中读取文件时,您的文件不包含任何内容。