Thread: Serializing classes

  1. #1
    Registered User
    Join Date
    May 2011
    Posts
    29

    Serializing classes

    So im wanting to be able to save the contents of classes in my code to a file and load them back at a later time, ive been looking at boost for serialization but i cant seem to find a good enough guide that makes sense.
    i want to save a class that is something like this:
    Code:
    class data {
    public:
    string words[128];
    float n[16];
    string last_string[8];
    };
    i want to be able to have a function that saves the contents of that class to a file, and another function that can load it back in.

    Thanks in advance,
    Jeromy

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    If you'd prefer to use a library rather than doing the serialization yourself, you could try Boost.Serialization: Serialization

    Everyone should try serialization by hand at least once, however.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  4. #4
    Registered User
    Join Date
    May 2011
    Posts
    29
    alright, so ive written my own little method of serializing a class, but im having trouble reading the strings i write to the file...

    my class:
    Code:
    class datas
    {
          public:
                 string word[3];
                 int n;
                 int a[5];
                 
                 int save(const char *filename)
                 {
                     ofstream file (filename, ios::out | ios::app | ios::binary);
                     if (file.is_open())
                     {
                           char buff[128];
                           char num[16];
                           itoa (n,num,2);
                           file.write (num, 16);
                           for(int i = 0; i < 3; i++)
                           {
                                   char *cc = new char[word[i].size() + 1];
                                   cc[word[i].size()] = 0;
                                   memcpy(cc,word[i].c_str(),word[i].size());
                                   file.write (cc, 128);
                           }
                     }
                     file.close();
                 }
                 
                 int load(const char *filename)
                 {
                     ifstream rfile (filename, ios::in | ios::binary);
                     char rnum[16];
                     rfile.read (rnum, 16);
                     n = binti(rnum);
                     for(int i = 0; i < 3; i++)
                     {
                             char buff[128];
                             rfile.read (buff, 128);
                             word[i] = buff;
                     }
                     rfile.close();
                 }
    };
    it will save and load the integer easily, but im not really sure what to do with the strings...

  5. #5
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Write down the string lengths in binary before you dump the strings. That way you read in the string length first and know what to do next. This was covered by the link Salem gave earlier.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Code is a ticking time bomb. There is no need to go all C when serializing. Plus it's leaking memory.
    All of these members can just be serialized with the >> operator.
    Just write size of array, then call operator >> for each array member. Then do the reverse.
    Or just use Boost Serialize, which is 100% safe, and can serialize standard STL constructs such as vector.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Quote Originally Posted by Elysia
    All of these members can just be serialized with the >> operator.
    Binary files only use read and write to do anything. The friendly operators >> and << are for text mode, since formatting takes place. You do not need to format bits.
    Last edited by whiteflags; 06-13-2011 at 04:02 PM.

  8. #8
    Registered User
    Join Date
    May 2011
    Posts
    29
    @whiteflags, what do you mean i dont need to format bits?

  9. #9
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Quote Originally Posted by Whyrusleeping View Post
    @whiteflags, what do you mean i dont need to format bits?
    That reply wasn't meant for you, and I edited the post in question to remove the confusion. But yes, you don't need to format bits. You might have endianness issues, but stream operator>> and operator<< do nothing about that.

    Quote Originally Posted by Elysia
    All of these members can just be serialized with the >> operator.
    I've quoted exactly where I think Elysia is wrong, again. The only way to work with binary files (using standard streams) is with read and write, not with operator>> or operator<<. I don't have a problem with the rest of his post.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You don't need a binary format. Text format works just fine and is more portable to boot.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    I think OP knows that Elysia, but it isn't your decision to make.

  12. #12
    Nasal Demon Xupicor's Avatar
    Join Date
    Sep 2010
    Location
    Poland
    Posts
    179
    Then again, OP is not using strict binary format at all. Just look how he uses itoa() to put integer as text. Since OP's using C++ it'd be much cleaner to just use << operator. Or save it as binary, and remember about the right endianess. (Also, OP, really take care of that leak that Elysia mentioned, it's there).

    Salem's link to C++ FAQ Lite on serialization is something good to read and outlines trade offs of text vs binary formats pretty well. OP, if you didn't read it yet - please do. You'll probably get even more detailed info than you can digest.

  13. #13
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Whyrusleeping View Post
    it will save and load the integer easily, but im not really sure what to do with the strings...
    Because you've translated the integers into text, written that into a 16 byte block, and written/read the same size block. I presume binti() reverses the mechanics of atoi() by reading a null terminated string, meaning if the int is 5, 14 bytes of those blocks are just garbage.

    You only need 4 bytes to store an int (on most systems; if you want to make this really really portable you would need a header indicating the sizeof(int), and nb. your 16 byte block has the same issue), if you do not translate it into text. The file you are working with has to be treated as binary anyway because you are dependent on the presence of '\0' bytes.

    WRT the strings, you can use the null terminator there as well.

    However, that means you do have to use the low level read and write because you have to deal with byte values and null, which text mode will screw-up.

    Conta Elysia, I do not think there is any way to serialize using text mode UNLESS you come up with a notation schema like JSON or XML. You cannot simply write everything out as a string into a text file and read it back in and magically guess where one thing begins and another ends.* To summarize: you need to choose between all text using a notation schema, or binary. If the later, you do not need to translate anything into text and you can find the end of a string via a zero byte (null terminator). Just make sure that your method appends them.

    * You could almost do it by prefixing variable length items with an integer indicating their length, as whiteflags says. However, what if you have a string "66varx"? That will get written as "666varx"? How do you know whether this is a 6 byte string beginning with 66v, or a 66 byte string beginning with 6v, or a 666 byte string beginning with v? Either you need to use a '\0' as a separator, or use some notation schema which amounts to the same thing (eg, | as seperator, or " " as bounds). A parallel problem will occur with variable length arrays/vectors. Etc...binary does not have this problem because an int is always four bytes. I know I've said this already, but your translation of ints into fixed 16 char blocks is pointless and amounts to the same thing -- you need binary to read them, so the text translation is redundant.
    Last edited by MK27; 06-14-2011 at 04:25 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  14. #14
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Since my advice is being misunderstood, if you write the integer down in bits then there should be no confusion as long as you understand the format. It's literally just reading the first four bytes (or whatever) and folding that into an int and using that as a basis for the next N bytes of string. My advice has everything to do with serializing in bits and nothing to do with how confusing text parsing can be.

  15. #15
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by whiteflags View Post
    My advice has everything to do with serializing in bits and nothing to do with how confusing text parsing can be.
    Yeah, I would do it your way too, but making that case might involve demonstrating how confusing text parsing can be (even if you get to use << and >>, lol). I hope that was clear.

    If you want to use text because you want a human readable format use an existing library for JSON or XML (the former is much nicer and sort of almost C++ native).
    Last edited by MK27; 06-14-2011 at 05:01 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Conversions between base classes and derived classes
    By tharnier in forum C++ Programming
    Replies: 14
    Last Post: 03-18-2011, 10:50 AM
  2. Classes access other classes local variables
    By parad0x13 in forum C++ Programming
    Replies: 6
    Last Post: 01-14-2010, 04:36 AM
  3. Serializing/deserializing problem
    By vsla in forum C Programming
    Replies: 3
    Last Post: 04-21-2008, 03:55 PM
  4. Serializing problem.. (can't use >> operator)
    By RancidWannaRiot in forum Windows Programming
    Replies: 2
    Last Post: 10-29-2005, 11:10 AM
  5. Serializing a class
    By Prog.Patterson in forum C++ Programming
    Replies: 4
    Last Post: 10-27-2005, 10:21 PM