GCC on Windows
#include <stdio.h>
#include <stdlib.h>
struct test {
int n1;
int n2;
};
int main() {
FILE *f;
f = fopen("test.dat", "w");
struct test test1 = {10, 10};
fwrite(&test1, sizeof(struct test), 1, f);
fclose(f);
struct test test2;
f = fopen("test.dat", "r");
while(fread(&test2, sizeof(struct test), 1, f))
printf("n1=%d n2=%d\n", test2.n1, test2.n2);
fclose(f);
return 0;
}
If I set test1 to 10,10
then fwrite will write 10 bytes to file: 0D 0A 00 00 00 0D 0A 00 00 00
(each 4-byte int will be padded with a 0D carriage return character before it)
If I set test1 to 11,11
then fwrite will write 8 bytes to file: 0B 00 00 00 0B 00 00 00
(as I would expect)
If I set test1 to 9,9
then fwrite will write 8 bytes to file: 09 00 00 00 09 00 00 00
(as I would expect)
If I set test1 to 9,10
then fwrite will write 9 bytes to file: 09 00 00 00 0D 0A 00 00 00
The 9 gets 4 bytes as expected, but the 10 gets padded with an extra 0D byte, resulting in 5 bytes. What is so special about the number 10 that requires this padding? And why do both smaller and larger numbers (8, 9, 11, 12, 13, 14, etc) not get padded? I thought maybe GCC is confusing the number 10 for a new-line character (a new-line is 10 is acsii), but this does not explain how fread is able to get the number 10 back out correctly.
And how do I write a struct to file without getting this extra padding on the number 10? Thank you.
CodePudding user response:
You opened the file in text mode, so every \n
gets a carriage return appended.
You should write (and read) binary data in binary mode instead (fopen(..., "wb")
) -- this will be much faster and avoids surprises (and also requires only 8 bytes, which is what sizeof(struct test)
is).
What is so special about the number 10 that requires this padding?
The number 10
just happens to be the ASCII code for newline (\n
) character.
CodePudding user response:
You are writing and reading in text mode.
Open the file with the flags "wb" and "rb". This will treat the files as binary files.