Writing structs to a file

Started by
12 comments, last by Shadowflare 19 years, 5 months ago
Hello, I am trying to save a struct containing character arrays (char string[16], not char *string) to a file. I have done much research and turned up nothing concerning a way to do this. All I've managed is saving structs containing numbers. If it's even possible to do it, how could I go about this? Thank you!
Advertisement
Are you using the C or C++ standard library routines? And what have you tried to write structs with numbers out to a file? Functions like fwrite() or std::basic_ostream::write() do the trick for me.
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke
Well, if you want to just save the data in a binary format, you can use fwrite() to write out all the struct data to the file. If you want to be able to open the file up and be able to see human-readable characters, you should write the data line-by-line or however else using something like fputs().

To write the entire structure to a binary file, you can do something like this:

// Little player structstruct player_t{    char name[32];    int life;};int WriteStructToFile(player_t *ch, const char *filename){    FILE *fp = fopen(filename, "wb");    if(fp)    {        fwrite(ch, sizeof(player_t), 1, fp);        fclose(fp);        return 1;    }    else	return 0;}


-noix-
In this world gone mad, we won't spank the monkey; the monkey will spank us.
Everything is possible my man. It's just you'll have to do it manually that's all.
If you directly write that structure to a file it will write the value of string (a memory address) instead of what is stored within that address since it is a memory pointer (Yes char* & char [] are for sake of argument exactly the same thing).
If you want to store that structure you are going to have to do it manually. make some export & input function that's all, instead of just expecting to dump the contents of memory that store that structure & expect it to work. You've failed to mention weather you're using c or c++ although many connect the term struct with C & class with C++ (although both serve the same purpose in C++, just different default access).

But either way the theory is the same:
Just write the string out as you would normal text to a file & do the same for each member in the structure. Make sure you keep the same order on load. Erm, to be short.. just write it to file one thing @ a time. Can't see what trouble or confusion you could have with that. Looks like you've just jumped ahead too fast that's all. Your brain just needs to learn some more code concept. You'll cram it all in there in the end.

Seek & you shall find knowledge & understanding

///
Edit: wow 2 people posted before me, gettin slow n old :(
//
_______________________________ ________ _____ ___ __ _`By offloading cognitive load to the computer, programmers are able to design more elegant systems' - Unununium OS regarding Python
Quote:Original post by ProPuke
Yes char* & char [] are for sake of argument exactly the same thing


This is actually not true for strings within structures. Try this to test your hypothesis:

typedef struct {    char Cool[32];    int  SomeStuff;} Test1;typedef struct {    char BestEver[1024];    int SomeStuff;} Test2;cout << "Size 1 is " << sizeof(Test1) << "Size 2 is " << sizeof(Test2) << endl;


If your hypothesis is correct, then Test1 and Test2 would be the same size. In my experience, this has never been the case ;~).
I wrote up a quick test just to make sure I didn't forget something. It worked fine:
#include <cstdio>struct s{  char a[16];  char b[16];};int main(){  s v;  strcpy(v.a, "0123456789ABCDE");  strcpy(v.b, "~!@#$%^&*()_+|");  FILE* pFile = fopen("Test.dat", "wb");  fwrite(&v, sizeof(v), 1, pFile);  fclose(pFile);  return 0;}


And as Apocryphiliac said, char* and char[] are not the same in this context. The former stores only a single (typically 4-byte) pointer. It may point to memory elsewhere, but if you try to write the struct out to a file using fwrite() or ostream::write(), you're only going to write the pointer values out to memory, not what they point to. This is not the desired behavior in almost all cases. However, with char[], the character array is stored literally in the struct, there is no pointer involved at all in this context, so the bytes get written out just as you would expect.
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke
Bah I knew people would complain if I said that :(
I only said "for sake or argument" although I realize I probally shouldn't of said that @ all. Since it's an array it will be allocated in the structure, & will be dereferenced by default; But ergh.. I forget what my point was. Hmm.. nope it's gone sorry
_______________________________ ________ _____ ___ __ _`By offloading cognitive load to the computer, programmers are able to design more elegant systems' - Unununium OS regarding Python
Quote:Original post by ProPuke
... good stuff ...


To expand on this, it is a good idea to write how many bytes long the array is in the file. This way, you can reserve a buffer long enough to hold the data before you read it in. This can prevent some buffer overrun errors as long as you adhere to that length.

struct PERSON {    int age;    char *name;}int write_struct(FILE *file, struct PERSON *person){    int length;    ASSERT(file != NULL);    ASSERT(person != NULL);    ASSERT(person->name != NULL);    fwrite(&person->age, sizeof(person->age), 1, file);    /* here i'm calculating the total number of bytes     * occupied by the string. i'm not counting on     * the size of each character in the string being     * one byte.     */    length = strlen(person->name) * sizeof(char);    /* we write the size in bytes of the string, not     * the number of characters. this will help prevent     * buffer overruns when you read the file in later    */    fwrite(length, sizeof(length), 1, file);    fwrite(person->name, 1, length, file);    return 0;}int read_struct(FILE *file, struct PERSON *person){    int length;    ASSERT(file != NULL);    ASSERT(person != NULL);    fread(&person->age, sizeof(person->age), 1, file);    /* read the number of bytes to allocate. when we     * wrote the value originally, we calculated byte     * length, not number of characters.    */    fread(&length, sizeof(length), 1, file);    person->name = malloc(length);    fread(person->name, 1, length, file);    return 0;}
Quote:Original post by smr
Quote:Original post by ProPuke
... good stuff ...


To expand on this...

Ahh yes i often say that... No wait.. I didn't say that. Huh? wha.. *explodes*
_______________________________ ________ _____ ___ __ _`By offloading cognitive load to the computer, programmers are able to design more elegant systems' - Unununium OS regarding Python
Quote:Original post by ProPuke
Quote:Original post by smr
Quote:Original post by ProPuke
... good stuff ...


To expand on this...

Ahh yes i often say that... No wait.. I didn't say that. Huh? wha.. *explodes*


You're making my brain hurt!

This topic is closed to new replies.

Advertisement