I have a small example program written in C. I have a main that call a function writeFile
that writes some numbers in a binary file. Then I call overwrite
to replace 0 with 1 and finally I print the result.
This is the code:
#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;
}
This code works with Linux, but when I run the same code on Windows the output is this:
---------BEFORE--------
Read test.dat:
3
2
0
4
-----------------------
Overwriting...
---------AFTER---------
Read test.dat:
3
2
1
2
Not only 0 was replaced by 1 but also the last number changed. Someone can help me to understand why this happens?
Another problem is that in the overwrite
I must use i
to stop the while because without the i<4
I get an infinite loop (only with Windows).
I tested this code on Windows 8.1 compiled with gcc 4.8.1 (from MinGW). On my Linux machine I tested the code with gcc 5.1.1.
Thank you all,
It's because you need to fflush()
after the fwrite()
, since you should not call fread()
after calling fwrite()
without an intervening call to fflush()
,
This is the section of the standard that is relevant in this case
7.21.5.3 The
fopen
function
- 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 thefflush
function or to a file positioning function (fseek
,fsetpos
, orrewind
), 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.
It's weird that this section is within fopen()
function since it involves fread()
and fwrite()
, which is where I was looking for an answer.
You can also see that my previous answer worked but not for the reason I stated in it, instead the explanation is found in the paragraph above.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With