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

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

#include  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  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; } } 

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

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

当使用更新模式打开文件时(’+’作为上述模式参数值列表中的第二个或第三个字符),可以在关联的流上执行输入和输出。 但是,输入不应直接跟随输入而不干涉fflushfunction或文件定位function(fseek,fsetpos或rewind),并且输入不应直接跟随输出而不干预文件定位函数,除非输入操作遇到文件结尾。

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

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

看到这个答案为什么总是需要fseek或fflush …

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

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