HELP: Class object I/O

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Andreas Palsgård

    HELP: Class object I/O

    Hey.. i want to write a class object containing both strings and integers,
    to a file on disk, and be able to read it properly again at another time. I
    made the code below... it doesn't work, but what am i doing wrong.

    thanx
    Andy
    -----------------------------------
    #include <fstream>
    #include <iostream>
    #include <string>
    using namespace std;

    class person
    {
    protected:
    string name,colour;
    int age;
    public:
    void getdata()
    {
    cout << "Enter name:" ; cin >> name;
    cout << "Enter Age:"; cin >> age;
    cout << "Enter colour:"; cin >> colour;
    }
    void showdata()
    {
    cout << "Name: " << name << endl;
    cout << "Age:" << age << endl;
    cout << "Colour:" << colour << endl;
    }
    string get_name(){ return name;}
    int get_age(){ return age;}
    string get_colour(){ return colour;}
    };

    person tim;

    void file_in(){
    person temp_pers;
    ifstream infile("person. dat", ios::in | ios::binary);
    infile.read(rei nterpret_cast<c har*>(&temp_per s),sizeof(temp_ pers));
    infile.close();
    tim = temp_pers;
    cout << temp_pers.get_n ame() << endl;
    cout << temp_pers.get_a ge() << endl;
    cout << temp_pers.get_c olour() << endl;
    }
    void file_out(){
    tim.getdata();
    person temp_pers;
    temp_pers = tim;
    ofstream outfile("person .dat", ios::binary | ios::out | ios::trunc);
    outfile.write(r einterpret_cast <char*>(&temp_p ers),sizeof(tem p_pers));
    outfile.close() ;
    cout << temp_pers.get_n ame() << endl;
    cout << temp_pers.get_a ge() << endl;
    cout << temp_pers.get_c olour() << endl;
    }
    /////////////////////////////
    int main()
    {
    file_out();
    //file_in();
    return 0;
    }


  • Ron Natalie

    #2
    Re: Class object I/O


    "Andreas Palsgård" <123pals@get2ne t.dk(fjern 123)> wrote in message news:3f85a45e$0 $54844$edfadb0f @dread11.news.t ele.dk...[color=blue]
    > Hey.. i want to write a class object containing both strings and integers,
    > to a file on disk, and be able to read it properly again at another time. I
    > made the code below... it doesn't work, but what am i doing wrong.
    >[/color]
    You posted this already. You can not write out most classes (other than
    the most simple) by casting their pointer to char* and calling Write.
    Your book, if it actually says to do that, is worse than useless. Burn it.
    The problem is that classes (such as string) may contain pointers to
    data elsewhere that is neither written by your hack nor properly restored
    when read in. Further you may stomp on C++ overhead for things like
    virtual functions that you have no business accessing.


    Comment

    • klaas

      #3
      Re: HELP: Class object I/O

      Andreas Palsgård wrote:
      [color=blue]
      > Hey.. i want to write a class object containing both strings and integers,
      > to a file on disk, and be able to read it properly again at another time. I
      > made the code below... it doesn't work, but what am i doing wrong.
      >[/color]
      the problem is:
      you don't know the size of the data you are writing to the file in advance.
      You have to make any char * into a char[fixed_size]
      to be able to let any size_of(your_ob ject) return a descent value.
      that way your reinterpret_cas t<hex> won't fail....

      so no char * pointers please...

      Comment

      • Moonlit

        #4
        Re: Class object I/O

        Hi,

        Object serialization is a great thing, unfortunately there is no magic
        behind it. Do the following:

        Define a function (possibly operator<< or serialize with in = false ) to
        write every value of the class to disk.

        Define a function ( possibly operator>> or serialize ( with in = true) to
        read every value from disk.

        For aggregated classes call the serialize member with the "in" or the
        operator>> or operator<< parameter.

        This will cause a tree of serialization to occur If every class knows how to
        correctly write and read its values it will succeed.

        In a few words, every object is responsible for reading or writing itself to
        persistent storage.

        Regards, Ron AF Greve.


        "Andreas Palsgård" <123pals@get2ne t.dk(fjern 123)> wrote in message
        news:3f85a45e$0 $54844$edfadb0f @dread11.news.t ele.dk...[color=blue]
        > Hey.. i want to write a class object containing both strings and integers,
        > to a file on disk, and be able to read it properly again at another time.[/color]
        I[color=blue]
        > made the code below... it doesn't work, but what am i doing wrong.
        >
        > thanx
        > Andy
        > -----------------------------------
        > #include <fstream>
        > #include <iostream>
        > #include <string>
        > using namespace std;
        >
        > class person
        > {
        > protected:
        > string name,colour;
        > int age;
        > public:
        > void getdata()
        > {
        > cout << "Enter name:" ; cin >> name;
        > cout << "Enter Age:"; cin >> age;
        > cout << "Enter colour:"; cin >> colour;
        > }
        > void showdata()
        > {
        > cout << "Name: " << name << endl;
        > cout << "Age:" << age << endl;
        > cout << "Colour:" << colour << endl;
        > }
        > string get_name(){ return name;}
        > int get_age(){ return age;}
        > string get_colour(){ return colour;}
        > };
        >
        > person tim;
        >
        > void file_in(){
        > person temp_pers;
        > ifstream infile("person. dat", ios::in | ios::binary);
        > infile.read(rei nterpret_cast<c har*>(&temp_per s),sizeof(temp_ pers));
        > infile.close();
        > tim = temp_pers;
        > cout << temp_pers.get_n ame() << endl;
        > cout << temp_pers.get_a ge() << endl;
        > cout << temp_pers.get_c olour() << endl;
        > }
        > void file_out(){
        > tim.getdata();
        > person temp_pers;
        > temp_pers = tim;
        > ofstream outfile("person .dat", ios::binary | ios::out | ios::trunc);
        > outfile.write(r einterpret_cast <char*>(&temp_p ers),sizeof(tem p_pers));
        > outfile.close() ;
        > cout << temp_pers.get_n ame() << endl;
        > cout << temp_pers.get_a ge() << endl;
        > cout << temp_pers.get_c olour() << endl;
        > }
        > /////////////////////////////
        > int main()
        > {
        > file_out();
        > //file_in();
        > return 0;
        > }
        >
        >[/color]


        Comment

        • klaas

          #5
          Re: HELP: Class object I/O

          klaas wrote:[color=blue]
          > Andreas Palsgård wrote:
          >[color=green]
          >> Hey.. i want to write a class object containing both strings and
          >> integers,
          >> to a file on disk, and be able to read it properly again at another
          >> time. I
          >> made the code below... it doesn't work, but what am i doing wrong.
          >>[/color]
          > the problem is:
          > you don't know the size of the data you are writing to the file in advance.
          > You have to make any char * into a char[fixed_size]
          > to be able to let any size_of(your_ob ject) return a descent value.
          > that way your reinterpret_cas t<hex> won't fail....
          >
          > so no char * pointers please...
          >[/color]
          If you have the fixed size issue ready i can give you a wrapper class
          that implement harddisk based arrays...
          let me know

          Comment

          • Andreas Palsgård

            #6
            Re: Class object I/O

            well... actually i found this out:
            My little program deosn't work with strings... but if you convert strings to
            char[] it works perfectly.
            You can write the whole object to a file with reinterpret_cas t[char*]...

            Andreas

            "Ron Natalie" <ron@sensor.com > wrote in message
            news:3f85a74f$0 $198$9a6e19ea@n ews.newshosting .com...[color=blue]
            >
            > "Andreas Palsgård" <123pals@get2ne t.dk(fjern 123)> wrote in message[/color]
            news:3f85a45e$0 $54844$edfadb0f @dread11.news.t ele.dk...[color=blue][color=green]
            > > Hey.. i want to write a class object containing both strings and[/color][/color]
            integers,[color=blue][color=green]
            > > to a file on disk, and be able to read it properly again at another[/color][/color]
            time. I[color=blue][color=green]
            > > made the code below... it doesn't work, but what am i doing wrong.
            > >[/color]
            > You posted this already. You can not write out most classes (other than
            > the most simple) by casting their pointer to char* and calling Write.
            > Your book, if it actually says to do that, is worse than useless. Burn[/color]
            it.[color=blue]
            > The problem is that classes (such as string) may contain pointers to
            > data elsewhere that is neither written by your hack nor properly restored
            > when read in. Further you may stomp on C++ overhead for things like
            > virtual functions that you have no business accessing.
            >
            >[/color]


            Comment

            • Thomas Matthews

              #7
              Re: Class object I/O

              Andreas Palsgård wrote:[color=blue]
              > well... actually i found this out:
              > My little program deosn't work with strings... but if you convert strings to
              > char[] it works perfectly.
              > You can write the whole object to a file with reinterpret_cas t[char*]...[/color]

              You _can't _ use reinterpret_cas t<> on a string. It is a complex class
              and not a simple type. Use the string::c_str() method for conversion
              to an array of characters (C-style string) and a constructor for
              converting from a C-style string to a std::string.

              [color=blue]
              >
              > Andreas[/color]

              1. Don't Top-Post (replies are appended to the bottom, or interspersed
              throughout).
              2. Strings are known as variable record types when serializing.
              (See also C++ faq about serializing).
              You have to decide whether you want to use the
              [quantity][text] or [text][sentinel]
              layout.
              3. Strings are one of those types that is best serialized in one
              form, but used internally in another. Endianism is another
              of these same issues.

              In my Binary_Stream class, I have chose the [quantity][text]
              layout. I also have every class write out their own members.



              --
              Thomas Matthews

              C++ newsgroup welcome message:

              C++ Faq: http://www.parashift.com/c++-faq-lite
              C Faq: http://www.eskimo.com/~scs/c-faq/top.html
              alt.comp.lang.l earn.c-c++ faq:

              Other sites:
              http://www.josuttis.com -- C++ STL Library book
              http://www.sgi.com/tech/stl -- Standard Template Library

              Comment

              Working...