0

It is possible to convert the following Student class to a binary file by writing it with ios::binary

#include <fstream>
#include <iostream>
using namespace std;

class Student{
    public:
        char name[40], address[120], gender;
        double age;
        bool is_blabla;
};

int main() {

    Student one;
    strcpy(one.name, "Cancan Can");
    strcpy(one.address, "example example exampla");
    one.gender = 'M';
    one.age = 25;
    one.is_blabla = true;

    ofstream ofs("fifthgrade.ros", ios::binary);
    ofs.write((char *)&one, sizeof(one));

    Student two;
    ifstream ifs("fifthgrade.ros", ios::binary);
    ifs.read((char *)&two, sizeof(two));

    // check if the data is OK
    cout << "Student Name: " << two.name << endl;


    return 0;
}

The file looks like as follows:

https://i.sstatic.net/ZU5C7.png

So how can I do the same thing to convert the class to a byte (or say char*) array in this case?

Edit: But in this case, Let's say I have a class having methods. The answers you gave is telling me to write my own bitwise operators to serialize a complex class. Can you refer to a good source teaching how it can be done or a small sample/example for it?

Edit2: I have to avoid using extra libraries because I may deserialize the serialized code on a machine/compiler that I cannot import most of the libraries (for example I will try to deserialize the code on an nvcc compiled code).

Example dummy class would be like this:

class Student{
    public:
        char name[40], address[120], gender;
        double age;
        bool is_blabla;

        void set_values (int,int);
        int doubleage() {return age*2;}
};
4
  • As said in the answers here below, just copy the data into a buffer (vector<char>, string, t hey all work fine. Note that all this works fine if you don't have complex types inside your class, ie. if your class is a POD (plain old data) If you start having dynamic allocations, things get complicated and you will need to provide your own way to serialize/deserialize objects. Usually this is done by implementig operators << and >> In C++11 you have a is_pod method to check if your structure is a pod. Commented Oct 23, 2014 at 11:57
  • 2
    It's already complicated due to endianness and alignment. That is, watch your assumptions on how portable this serialised format would be (read: not at all). Commented Oct 23, 2014 at 11:59
  • @dau_sama, the example was a dummy one. I actually have complex classes having dynamic states and methods. So I see what you say. Can you please refer me a resource/website so that I can see how to use bitwise operators to serialize a complex class? Commented Oct 26, 2014 at 7:26
  • @cancan if you have complex classes, it's not going to be easy. you can check boost.org/doc/libs/1_55_0/libs/serialization/doc/index.html Commented Oct 29, 2014 at 18:13

3 Answers 3

4

Just use a std::stringstream rather than std::ofstream.

Then, access the char* using std::stringstream::str() (This return's a std::string, on which you can retrieve a char* using std::string::c_str()).

Sign up to request clarification or add additional context in comments.

2 Comments

So, was it good or bad he copied the raw bytes from his student object into the stream? And what about ios::binary and what else he asked about?
I don't see why the produced char* could not be written to a ios:binary file.
2

All objects can be accessed as their constituent chars, just get a pointer and cast it.

Still, even if you want to write it to a binary file (in contrast to writing a textual representation), do not just write its raw bytes:

  • The object might contain a number of non-value-bits (Like padding, unused buffers, whatever). Those might contain previously recorded information, which you should not leak.
  • The object might contain pointers, handles or other references to additional data. Those cannot be recovered from a bitwise-copy, as the information they indicate is the important part and won't be there.

BTW: ios::binary just disables translation of text-files. (Identity on Unixoids, newline-conversion on windows...)

5 Comments

Could you elaborate on "non value bit"? what do you mean?
"All objects can be accessed as their constituent chars, just get a pointer and cast it." Isn't this dangerously misleading? It's true, but it ignores what semantically constitutes an "object". i.e. you cannot serialise a std::string by simply casting a pointer to the "container".
@LightnessRacesinOrbit: And I later explain why that's not always good enough.
"non-value-bits" may also include things like vTable entries in derived classes.
@icabod: The actual vtable certainly contributes to the value, as it determines the actual type. Thus I would rather put it under hidden pointers, handles and other fun.
1

If you need a more enhanced way, consider the following ways:

  1. Boost.Serialization (http://www.boost.org/doc/libs/1_56_0/libs/serialization/doc/index.html)
  2. Google Protocol Buffers (https://developers.google.com/protocol-buffers/)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.