使用“r +”在fopen上windows vs linux
我正在打开一些正在打开,阅读和修改文本文件的代码。快速(简体)的例子是:使用“r +”在fopen上windows vs linux
#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上,与海湾合作委员会(4.6.2)运行此代码编译,并修改文件的5日线。使用Visual C++ 2010编译的Windows7上运行的相同代码运行并声称已成功(报告返回码为19个字符,而perror
表示“无错误”),但未能替换该行。
在Linux上我的文件具有完全的权限:
-rw-rw-rw- 1 mike users 191 Feb 14 10:11 test.txt
而据我可以告诉它是相同的Windows:
的test.txt(右键) - >属性 - >安全
检查“允许”为读取&写入用户,系统和管理员。
我在Windows上使用MinGW的gcc获得了相同的结果,所以我知道它不是一个Visual C++“功能”。
我失去了一些东西明显,或者是我没有得到任何错误的情况,也没有输出只使用r+
与fopen()
在Windows上的无证“功能”?
编辑:
似乎即使在Microsoft's site他们说 “R +” 应该打开阅读和书面方式。他们还提出了这样一个字条:
当“R +”,“W +”,或“+”访问类型指定,阅读和写作都被允许(该文件被认为是开放的“更新”) 。但是,当您在读取和写入之间切换时,必须存在干预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);
...
无济于事。
读取和写入可被以任何顺序的读/写数据流混合。 请注意,ANSI C要求文件定位功能在输出和输入之间插入 ,除非输入操作遇到 文件结束。 (如果不满足这个条件,则允许读取 返回除最近写入之外的写入结果。)因此,它是一个很好的做法(并且实际上有时在Linux下有必要)将 设置为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 functoin):
当一个文件被打开与更新模式( '+' 作为第二或第三 字符在上面的模式参数值列表中),输入和 输出都可以在关联的数据流上执行,但输出 不应直接跟随输入,而不需要中间调用fflush函数的 或文件定位功能(fseek, fsetpos或倒带),并且输入不应该直接跟在输出 之后,除非 输入操作遇到文件结束,否则不会调用文件定位功能。
您是否在写入操作之后尝试使用'fflush'刷新流? – Cyclonecode 2013-02-14 15:47:36
我不确定这是否是问题,但您可能需要在文件 – Hasturkun 2013-02-14 15:48:47
@KristerAndersson - yup之间切换读取和写入时调用'fseek',只是更新以澄清我在MSDN网站上看到说你的注释应该更新'f()'之一的流,所以我在写入之前和之后尝试了'fflush()',但没有骰子。 –
Mike
2013-02-14 15:51:46