c - Linux 和 Windows 之间 fwrite 的不同行为

标签 c linux windows fwrite

我有一个用 C 编写的小示例程序。我有一个调用函数的主程序 writeFile在二进制文件中写入一些数字。然后我调用overwrite用 1 替换 0,最后打印结果。

这是代码:

#include <stdio.h>

/* Print the content of the file */
void printFile(){
    printf("Read test.dat:\n");
    int r;
    FILE* fp = fopen("test.dat", "rb+");
    if(fp) {
    while(fread(&r,sizeof(int),1,fp)){
            printf("%d\n", r);
        }
    }
    fclose(fp);
}

/* Replace 0 with 1 */
void overwrite(){
    int   r;
    FILE *fp = fopen("test.dat", "rb+");
    if (fp) {
        int i=0;
        while (i < 4 && fread(&r, sizeof(int), 1, fp)) {
            i++;
            if (r == 0) {
                r = 1;
                fseek(fp,-sizeof(int),SEEK_CUR);
                fwrite(&r,sizeof(int),1,fp);
            }
        }
    }
    fclose(fp);    
}

/* Create original file */
void writeFile() {
    int b, b1, b2, b3, b4;

    b  = 3;
    b1 = 2;
    b2 = 0;
    b3 = 4;

    FILE *fp = fopen("test.dat", "wb");
    if (fp) {
        fwrite(&b, sizeof(int), 1, fp);
        fwrite(&b1, sizeof(int), 1, fp);
        fwrite(&b2, sizeof(int), 1, fp);
        fwrite(&b3, sizeof(int), 1, fp);
    }
    fclose(fp);    
}

int main() {
    writeFile();
    printf("---------BEFORE--------\n");
    printFile();
    printf("-----------------------\n");
    printf("Overwriting...\n");
    overwrite();
    printf("---------AFTER---------\n");
    printFile();
    return 0;
}

这段代码适用于 Linux,但是当我在 Windows 上运行相同的代码时,输​​出是这样的:

 ---------BEFORE--------
Read test.dat:
3
2
0
4
-----------------------
Overwriting...
---------AFTER---------
Read test.dat:
3
2
1
2

不仅 0 被 1 取代,而且最后一个数字也改变了。有人可以帮助我理解为什么会这样吗?

另一个问题是在overwrite我必须使用 i停止一会儿因为没有 i<4我得到一个无限循环(仅限 Windows)。

我在使用 gcc 4.8.1(来自 MinGW)编译的 Windows 8.1 上测试了这段代码。 在我的 Linux 机器上,我使用 gcc 5.1.1 测试了代码。

谢谢大家

最佳答案

这是因为你需要在 fwrite() 之后调用 fflush(),因为你不应该在调用 之后调用 fread() >fwrite() 没有对 fflush() 的干预调用,

这是与本案例相关的标准部分

7.21.5.3 The fopen function

  1. When a file is opened with update mode ('+' as the second or third character in the above list of mode argument values), both input and output may be performed on the associated stream. However, output shall not be directly followed by input without an intervening call to the fflush function or to a file positioning function (fseek, fsetpos, or rewind), and input shall not be directly followed by output without an intervening call to a file positioning function, unless the input operation encounters end-of-file. Opening (or creating) a text file with update mode may instead open (or create) a binary stream in some implementations.

这部分在 fopen() 函数中很奇怪,因为它涉及 fread()fwrite(),这是我的地方正在寻找答案。

您还可以看到我的 previous answer工作但不是因为我在其中陈述的原因,而是在上面的段落中找到了解释。

关于c - Linux 和 Windows 之间 fwrite 的不同行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31116131/

相关文章:

Windows 7 - 从开发人员的角度来看会有什么期望?

创建文件并使用系统调用操作向其中写入随机字符

c - 在 C 中的 strtok() 中包括 '\'

c - 列出 Windows 目录中的文件在 C 中不起作用

C - 读取文件和段错误

linux - 计算所有字符,包括 linux 中的空格

c++ - 为什么三字母在现代 C++ 编译器中会产生错误?

linux - 相当于 Bash 中的 select() 系统调用

windows - 多个 npm 安装失败(EPERM 错误)

windows - c :\program? 有什么技巧