Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

`fwrite` doesn't work directly after `fread`?

I have a program which uses stdio for reading and writing a binary file. It caches the current stream position and will not seek if the read/write offset is already at the desired position.

However, an interesting problem appears, that when a byte is read and the following byte is written, it doesn't actually get written!

Here is a program to reproduce the problem:

#include <cstdio>

int main() {
    FILE *f = fopen("test.bin", "wb");
    unsigned char d[1024] = { 0 };
    fwrite(d, 1, 1024, f);
    fclose(f);
    f = fopen("test.bin", "rb+");
    for (size_t i = 0; i < 1024; i++) {
        unsigned char a[1] = { 255 - (unsigned char)(i) };
        fflush(f);
        fwrite(a, 1, 1, f);
        fflush(f);
        fseek(f, i, SEEK_SET);
        fread(a, 1, 1, f);
        printf("%02X ", a[0]);
    }
    fclose(f);
    return 0;
}

You are supposed to see it write the bytes FF down to 00, however only the first byte is written because it does not follow a fread immediately.

If it seeks before fwrite, it acts correctly.

The problem happens on Visual Studio 2010/2012 and TDM-GCC 4.7.1 (Windows), however it works on codepad which I guess is due to it being executed on Linux.

Any idea why this happens?

like image 356
Alvin Wong Avatar asked Sep 05 '26 23:09

Alvin Wong


1 Answers

C99 §7.18.5.3/6 (quoted from N869 final draft):

“When a file is opened with update mode (’+’ as the second or third character in the above list of mode argument values) […] 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.”

like image 101
Cheers and hth. - Alf Avatar answered Sep 07 '26 18:09

Cheers and hth. - Alf