Linux和Windows之间fwrite的不同行为

Rob*_*Man 7 c linux windows fwrite

我有一个用C编写的小示例程序.我有一个main函数writeFile,它调用一个函数在二进制文件中写入一些数字.然后我调用overwrite0替换为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;
}
Run Code Online (Sandbox Code Playgroud)

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

 ---------BEFORE--------
Read test.dat:
3
2
0
4
-----------------------
Overwriting...
---------AFTER---------
Read test.dat:
3
2
1
2
Run Code Online (Sandbox Code Playgroud)

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

另一个问题是,overwrite我必须使用i停止,因为没有i<4我得到一个无限循环(只有Windows).

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

谢谢你们,

Iha*_*imi 7

这是因为你需要在fflush()之后fwrite(),因为你不应该fread()fwrite()没有干预电话的情况下拨打电话fflush(),

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

7.21.5.3 fopen功能

  1. 当使用更新模式打开文件时('+'作为上述模式参数值列表中的第二个或第三个字符),可以在关联的流上执行输入和输出.然而,输出不应直接跟随输入而没有插入调用fflush功能或文件定位功能(fseek,fsetpos,或rewind),并且输入不应直接跟随输出而没有中间呼叫到一个文件中的定位功能,除非输入操作遇到文件结尾.在某些实现中,打开(或创建)具有更新模式的文本文件可以改为打开(或创建)二进制流.

这很奇怪,这节中fopen()的功能,因为它涉及fread()fwrite(),这就是我一直在寻找一个答案.

您还可以看到我之前的答案有效但不是因为我在其中说明的原因,而是在上面的段落中找到了解释.

  • `fclose(fp)`应该在`fp!= NULL`分支中(这也适用于问题中的原始代码). (2认同)