在Windows和Linux上使用“r +”打开

我正在打开一些正在打开,阅读和修改文本文件的代码。 一个简单的例子是:

#include <stdio.h> int main() { FILE * fp = fopen("test.txt", "r+"); char line[100] = {'\0'}; int count = 0; int ret_code = 0; while(!feof(fp)){ fgets(line, 100, fp); // do some processing on line... count++; if(count == 4) { ret_code = fprintf(fp, "replaced this line\n"); printf("ret code was %d\n", ret_code); perror("Error was: "); } } fclose(fp); return 0; } 

现在在Linux上,用gcc(4.6.2)编译这个代码,并修改文件的第五行。 使用Visual C ++ 2010编译的Windows7上运行的相同代码运行并声称已成功(报告19个字符的返回代码, perror表示“无错误”),但未能replace该行。

在Linux上,我的文件具有完全的权限:

 -rw-rw-rw- 1 mike users 191 Feb 14 10:11 test.txt 

据我可以告诉它在Windows上是一样的:

test.txt(右键单击) – >属性 – >安全性
为用户,系统和pipe理员检查“允许”读写。

我在Windows上使用MinGW的gcc获得相同的结果,所以我知道这不是一个Visual C ++“function”。

我错过了一些明显的东西,或者是我没有得到任何错误,但也没有输出只是在Windows上使用r+fopen()的无证“特性”?


编辑:
即使在微软的网站上,他们也会说“r +”应该开放阅读写作。 他们也做了这个说明:

当指定“r +”,“w +”或“a +”访问types时,允许读取和写入(该文件被称为“update”打开)。 但是,当您在读取和写入之间切换时,必须有一个介入fflush,fsetpos,fseek或倒带操作。 如果需要,可以为fsetpos或fseek操作指定当前位置。

所以我试了一下:

  ... if(count == 4) { fflush(fp); ret_code = fprintf(fp, "replaced this line\n"); fflush(fp); printf("ret code was %d\n", ret_code); ... 

无济于事。

Solutions Collecting From Web of "在Windows和Linux上使用“r +”打开"

根据fopen()的Linux手册页 :

读取和写入可以以任何顺序混合在读取/写入流中。 请注意,ANSI C要求文件定位功能介于输出和输入之间,除非输入操作遇到文件结束。 (如果没有满足这个条件,那么允许一个读操作返回最近写操作的结果)。因此,把一个fseek(3)或者fgetpos(3) )在这样的流上的写入和读取操作之间的操作。 这个操作可能是一个明显的无操作(如在fseek(…,0L,SEEK_CUR)中被称为同步副作用)。

所以,当从一个文件读取和写入之间切换时,你总是应该调用fseek() (例如fseek(..., 0, SEEK_CUR) )。

在输入之后执行输出之前, fflush()不是什么好事 – 你需要执行一个查找操作。 就像是:

 fseek(fp, ftell(fp), SEEK_SET); // not fflush(fp); 

从C99标准(7.19.5.3/6“fopen函数):

当以更新模式打开文件(在上述模式参数值列表中,第二个或第三个字符为'+')时,输入和输出都可以在关联的流上执行。 然而,输出不应该直接跟随输入,而不需要中间调用fflush函数或文件定位函数(fseek,fsetpos或rewind),并且输入不应该直接跟随输出,而不需要中间调用文件定位函数,除非输入操作遇到文件结束。