c – 在windows vs 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)编译此代码,并修改文件的第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);
          ...

无济于事.

解决方法:

根据Linux man page for fopen()

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)).

相关文章

Windows2012R2备用域控搭建 前置操作 域控主域控的主dns:自...
主域控角色迁移和夺取(转载) 转载自:http://yupeizhi.blo...
Windows2012R2 NTP时间同步 Windows2012R2里没有了internet时...
Windows注册表操作基础代码 Windows下对注册表进行操作使用的...
黑客常用WinAPI函数整理之前的博客写了很多关于Windows编程的...
一个简单的Windows Socket可复用框架说起网络编程,无非是建...