我正在玩弄一些打开,阅读和修改文本文件的代码.一个快速(简化)的例子是:
#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)编译此代码,并修改文件的第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“功能”.
我错过了一些明显的东西,或者我没有得到任何错误,但也没有输出只是在Windows上使用r和fopen()的无证“功能”?
编辑:即使在Microsoft’s site,他们说“r”应该打开阅读和写作.他们还做了这个说明:
When the “r+”, “w+”, or “a+” access type is specified, both reading and writing are allowed (the file is said to be open for “update”). However, when you switch between reading and writing, there must be an intervening fflush, fsetpos, fseek, or rewind operation. The current position can be specified for the fsetpos or fseek operation, if desired.
所以我尝试过:
...
if(count == 4) {
fflush(fp);
ret_code = fprintf(fp, "replaced this line\n");
fflush(fp);
printf("ret code was %d\n", ret_code);
...
无济于事.
解决方法:
Reads and writes may be intermixed on read/write streams in any order.
Note that ANSI C requires that a file positioning function intervene
between output and input, unless an input operation encounters
end-of-file. (If this condition is not met, then a read is allowed to
return the result of writes other than the most recent.) Therefore it
is good practice (and indeed sometimes necessary under Linux) to put
an fseek(3) or fgetpos(3) operation between write and read operations
on such a stream. This operation may be an apparent no-op (as in
fseek(…, 0L, SEEK_CUR) called for its synchronizing side effect.
因此,在从文件读取和写入之间切换时,应始终调用fseek()(例如,fseek(…,0,SEEK_CUR)).