简体   繁体   中英

Strange value when reading from binary file with fread() in C

I have an issue that I can't solve...

I used fwrite to write an int value (among other values that come from a struct ) into a file that I've opened using fopen(file, "wb");

This worked fine, and when I view the contents of the file, I can see the HEX value of the int that I've "written" (and all the other values as well).

Next, I try to read the file. So, I open the file using fopen(file, "rb"); and start reading it using fread . The first int value is read correctly (eg 7) and all the other values after it - which belong to the first struct that I've written.

I then try to read the next struct and when I try to read the first int value, I receive a very strange number (eg 1140850688) but it should be 39 instead.

So the question is: Why is this happening? And how can I solve it?

My struct looks like this:

struct a {
    int a1;
    char* a2;
    struct b* a3;
    unsigned char a4; 
    int a5;
    char* a6; 
}

And the fread call looks like this: fread(&(tmpA->a1), sizeof(int), 1, file);

EDIT:

The fwrite part:

fwrite(&(tmpA->a1), sizeof(int), 1, file);
fwrite(tmpA->a2, sizeof(char), strlen(tmpA->a2), file);
fwrite(tmpA->a3, sizeof(struct b), 1, file);
fwrite(&(tmpA->a4), sizeof(unsigned char), 1, file);
fwrite(&(tmpA->a5), sizeof(int), 1, file);
fwrite(tmpA->a6, sizeof(char), strlen(tmpA->a6), file);

The fread is almost the same.

If you wrote a struct from a file, you should read a struct back; trying to read an int is not going to work. However, it rarely, if ever, makes sense two write out as binary a struct that contains pointers. You should either make them arrays of fixed size, or serialize them separately from your struct .

EDIT : (in response to posted code) Most likely the problem has to do with writing an unknown number of characters in the second call of fwrite . When you serialize a C string, you should write out the number of characters before writing the characters themselves, so that when you read you'd know how much characters to allocate and to read back:

int len = strlen(tmpA->a2);
fwrite(&len, sizeof(int), 1, file);    
fwrite(tmpA->a2, sizeof(char), len, file);
...
fread(&(tmpA->a1), sizeof(int), 1, file);
tmpA->a2 = malloc(tmpA->a1+1);
fread(tmpA->a2, sizeof(char), tmpA->a1, file);
tmpA->a2[tmpA->a1] = '\0';

I suspect your problem is on this line

fwrite(tmpA->a3, sizeof(struct b), 1, file);

where you are writing a struct . This struct will have padding bytes, as per this wikipedia article which will offset the rest of your data. You will likely have to come up with a better way of writing that struct to memory. This page provides additional explanation.

You can check to see if this is indeed the problem by checking if a4 has the value you expect, or by comparing the size of the entire struct versus the sum of the sizes of its members.

Also, these lines look dangerous:

fwrite(tmpA->a2, sizeof(char), strlen(tmpA->a2), file);
fwrite(tmpA->a6, sizeof(char), strlen(tmpA->a6), file);

they say that the length of the string being printed may vary in your stored data. strlen will give you the length of your string without counting the terminating \\0 so there is no good way to know where a string ends once you've written it. I can't imagine how you plan on reading the string back in.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM