Click here to Skip to main content
15,942,847 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
class student{
private:
    char name[50];
    int ID;
public:
    student(char* n, int id){
        strcpy(name, n);
        ID=id;
    }
};

class school{
private:
    char name[50];
    student* students[10];
public:
    school(char* n){
        strcpy(name,n);
        for(int i=0; i<10; i++){
            students[i]=NULL;
        }
    }

    void addStu(char* n, int id){
        students[0]=new student(n,id);
        students[1]=new student(n,id);
        students[2]=new student(n,id);
        students[3]=new student(n,id);
        students[4]=new student(n,id);
        students[5]=new student(n,id);
        students[6]=new student(n,id);
        students[7]=new student(n,id);
        students[8]=new student(n,id);
        students[9]=new student(n,id);
    }
};

int main(){
    school* s = new school("Kiss");
    s->addStu("Jason", 1000);
    ofstream sch;
    sch.open("school.dat" ios::out|ios::app|ios::binary);
    sch.write((char*)s, sizeof(school));
    sch.close();

}


'school' class has 'student' class as its attribute.

and I would like to write the school object 's' to a file.

Then I wanna read the file and load the school object back on the memory.

What I would like to ask is..
1. does the code works as intended, even if I wrote it as sizeof(school)?
2. would I get proper data from the file when I read it back?

that is my question.. I hope someone please help me~~

Thank you,

cheers,
Posted
Updated 15-Jul-11 23:52pm
v2

Have also a look at boost::serialization[^].
 
Share this answer
 
Comments
Richard MacCutchan 16-Jul-11 8:13am    
Much neater of course.
CPallini 16-Jul-11 8:44am    
Only if the OP wishes to use boost (and it isn't granted at all).
Sergey Alexandrovich Kryukov 17-Jul-11 23:27pm    
As far as I know, boost provides most comprehensive serialization; my 5.
--SA
This is rather fragile to write C++ object to file by writing their binary content. It will depend on which compiler and which compiler options you are using. On some plateform, interger are stored in big-endian format while on other little endian format is used.

A structure should be a POD (Plain old data) type if you decide to go this way as otherwise there could be additionnal content like virtual tables that could be messed up when reading back from a file.

The alignment will create holes in data. The above "structure" will typically be 56 bytes on a 32 bit plateform where 4 bytes alignment is generally used. If that programm is compiled in 64 bit, it might be 64 bytes... There are compiler options and pragma to control the alignement but there are not portable.

Typically, it would be best for you to try to find a library for that purpose as experts would have deal with those problems... In fact, XML format should be considered for configuration data and a database for tables of large data in most situations.

If your target is MFC or C++/CLI (and probably some other target), you might already have what you need. For example, in .NET, there is built-in support for XML.

If you want to write your own code, then you should write your own functions to read and write data. You should then have a utility class for reading and writing data.

class stream_helper
{
public:
    stream_helper(stream &the_stream_) : the_stream(the_stream_) { }

    int read_int() { /* code here */ }
    int read_string() { /* code here */ }


    void write_int(int value) { /* code here */ }
    void write_string(char const *text) { /* code here */ }

private:
    stream &the_stream;
};


You could also overload operators << and >> to make it more convenient to uses.

Without using an existing librairy, it will be hard to handle think like pointers (graph of objects) correctly. Also, typically some tracking should be added for validation and versionning.
 
Share this answer
 
Comments
Richard MacCutchan 16-Jul-11 9:08am    
My 5 for a good answer.
In a way, yes it would work, but you would not get the results you expect. The problem comes with your students, as they are all pointers, so when you write the school object, you are writing pointers to the students but not their content. When serialising/deserialising objects you should always get the object to save its own content, saving elemental types 'as is' and object types by iterating over each element or sub-object and getting them to save themselves. So for your school object you would do something like:
school.save();

// the save code is:
    write (name); // the character string, perhaps preceded by a length item.
    write (count); // the number of students in school
    foreach (student in school)
        student.save();

        // student.save code is
        {
            write (name); // see comment above
            write (ID);
        }

write (EOFmark); // signify no more data

To read back you would just reverse this process, creating new objects as required.
 
Share this answer
 
v2
Comments
CPallini 16-Jul-11 7:58am    
Excellent, my 5.
Legor 17-Jul-11 6:28am    
My Solution would hav elooked the same! 5ved
Richard MacCutchan 17-Jul-11 8:00am    
Thanks, I also liked Philippe's suggestions.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900