Reputation: 21
I'm working on a mailbox project, and I have these two structures:
struct mmbox_mail
struct mmbox_mail {
char *sender, *recipient;
char *obj, *date;
char flags;
size_t size;
};
and
mail_t
typedef struct{
struct mmbox_mail info;
void *body;
void *next;
} mail_t;
I cannot modify the structures' fields, because I need variable data (for this purpose I used char* instead of char[]).
Each mail_t structure is a mail. I need to save every mail of a user in a file, that could be binary or text file (but I think it's better with a binary file, because I have the void*
body that is difficult to save in plain text.
I tried to do this, but it seems like it doesn't work:
while(mailtmp != NULL){
fwrite(mailtmp, sizeof(mail_t), 1, fp);
/* next mail */
mailtmp=mailtmp->next;
}
while(mailtmp != NULL){ /* i have a list of mails and i use a mailtmp pointer to save each mail */
Could you help me? I tried to search everywhere but I never found someone that ask to save two structures, one inside one other.
Upvotes: 2
Views: 2868
Reputation: 273
well,you are storing the struct's pointer into file.not the data it point to.even you store the struct you want.it is hard to get it from file. i think you need a serialization component like google protocal buffer. then you can write a adaptor,translate the struct to probuf object,then store it to file.when you want,retr it.hoping it will help you:)
Upvotes: 0
Reputation: 2505
What you're doing is saving the literal binary representation of mail_t into the text file, which is just a bunch of pointers. What you want to do is something to the effect of:
fprintf( fp, "To: %s\nFrom: %s\n....\nContents: %*s\n\n", mailtmp->info.recipient, mailtmp->info.sender, mailtmp->info.size, mailtmp->body );
That will render the values pointed to as a string and save it to the file. A pointer to a location in memory held by your application is a bit useless to most people after said application closes ;)
EDIT: "Could you help me? I tried to search everywhere but i never found someone that ask to save two structures, one inside one other."
If you just had first class data types, such as ints or floats etc, your method would work perfectly. However, since you are using second class types, namely your char and void arrays, you have to actually specify how the data pointed to should be saved.
Upvotes: 0
Reputation: 793
Of course, that will not work as for strings it will copy the size of pointer, (usually 4 bytes). I see 3 options here:
In any case you would need to go through every field of the structure in order to write it to data file. As for reading, in first 2 cases you would have to do reading exactly in the order you wrote the data, in third case you would be able to read fields independently in any order.
In case you choose first method, for every string (char *) field write also zero-termination byte so that you always know where it ends when reading it back.
Upvotes: 3