Saving a binary file help.

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • G-Factor

    Saving a binary file help.

    Hi all

    I've just started learning about saving files. I got bit of a problem. The
    following code gives me an error about incompatible types. (Cannot covert
    from class character to char *). I would appreciate it if anyone could
    either help me out, or direct me to an online resource site that has
    information on saving/loading classes. I have found several tutorials, but
    they either do not really help (saving text files) or are too difficult for
    me to understand. Thanks


    class character
    {
    public:
    character();
    character(strin g charName);
    virtual ~character();

    string getCharName();

    private:
    string name;
    int age;
    };

    void saveFile(charac ter* characterFile)
    {

    ofstream writeFile;

    writeFile.open( "game.dat", ios::binary);

    writeFile.write ((char *)characterFile , sizeof(characte r));

    writeFile.close ();

    }



  • Gianni Mariani

    #2
    Re: Saving a binary file help.

    G-Factor wrote:[color=blue]
    > Hi all
    >
    > I've just started learning about saving files. I got bit of a problem. The
    > following code gives me an error about incompatible types. (Cannot covert
    > from class character to char *). I would appreciate it if anyone could
    > either help me out, or direct me to an online resource site that has
    > information on saving/loading classes. I have found several tutorials, but
    > they either do not really help (saving text files) or are too difficult for
    > me to understand. Thanks
    >
    >
    > class character
    > {
    > public:
    > character();
    > character(strin g charName);
    > virtual ~character();
    >
    > string getCharName();
    >
    > private:
    > string name;
    > int age;
    > };
    >
    > void saveFile(charac ter* characterFile)
    > {
    >
    > ofstream writeFile;
    >
    > writeFile.open( "game.dat", ios::binary);
    >
    > writeFile.write ((char *)characterFile , sizeof(characte r));[/color]

    DANGER above ... sizeof(characte r) returns the size of the character
    class NOT THE SIZE OF THE STRING.....

    I suggest you add a method

    operator const & string () const
    {
    return name;
    }

    and then you can

    writeFile << * characterFile;

    [color=blue]
    >
    > writeFile.close ();
    >
    > }
    >
    >
    >[/color]

    Comment

    • Fabio

      #3
      Re: Saving a binary file help.

      "Gianni Mariani" <gi2nospam@mari ani.ws> wrote in message
      news:3F09225E.9 030300@mariani. ws...[color=blue]
      > I suggest you add a method
      > operator const & string () const
      > {
      > return name;
      > }
      > and then you can
      > writeFile << * characterFile;[/color]

      And what about the 'age' field ?
      I guess G-Factor wanted to save both 'age' and 'name' field.

      Fabio


      Comment

      • G-Factor

        #4
        Re: Saving a binary file help.


        "Fabio" <fabioang.NOSPA M@libero.it> wrote in message
        news:bebeq3$b16 $1@newsreader.m ailgate.org...[color=blue]
        > "Gianni Mariani" <gi2nospam@mari ani.ws> wrote in message
        > news:3F09225E.9 030300@mariani. ws...[color=green]
        > > I suggest you add a method
        > > operator const & string () const
        > > {
        > > return name;
        > > }
        > > and then you can
        > > writeFile << * characterFile;[/color]
        >
        > And what about the 'age' field ?
        > I guess G-Factor wanted to save both 'age' and 'name' field.
        >
        > Fabio[/color]

        Yes, I want to save the entire class.


        Comment

        • Rolf Magnus

          #5
          Re: Saving a binary file help.

          Gianni Mariani wrote:
          [color=blue]
          > G-Factor wrote:[color=green]
          >> Hi all
          >>
          >> I've just started learning about saving files. I got bit of a
          >> problem. The following code gives me an error about incompatible
          >> types. (Cannot covert from class character to char *). I would
          >> appreciate it if anyone could either help me out, or direct me to an
          >> online resource site that has information on saving/loading classes.
          >> I have found several tutorials, but they either do not really help
          >> (saving text files) or are too difficult for me to understand. Thanks
          >>
          >>
          >> class character
          >> {
          >> public:
          >> character();
          >> character(strin g charName);
          >> virtual ~character();
          >>
          >> string getCharName();
          >>
          >> private:
          >> string name;
          >> int age;
          >> };
          >>
          >> void saveFile(charac ter* characterFile)
          >> {
          >>
          >> ofstream writeFile;
          >>
          >> writeFile.open( "game.dat", ios::binary);
          >>
          >> writeFile.write ((char *)characterFile , sizeof(characte r));[/color]
          >
          > DANGER above ... sizeof(characte r) returns the size of the character
          > class NOT THE SIZE OF THE STRING.....[/color]

          Well, that's only part of the problem. It will of course include the
          size of the string object, but that object probably contains a pointer
          to the actual string data. With that cast, only the pointer itself
          would be written to the file, _not_ the data it points to.
          If you don't have a good reason to write the data in binary form, don't.
          It's quite unportable (You can't write the structure on a PC and read
          it on a MAC, and maybe not even on the same PC using a different
          compiler), produces lots of problems (e.g. you can't use classes that
          contain pointers or virtual member function - wrt the C++ standard, you
          might only have a chance with PODs AFAIK) and in many cases isn't worth
          it.
          [color=blue]
          > I suggest you add a method
          >
          > operator const & string () const[/color]

          You probably meant:

          operator const string & () const
          [color=blue]
          > {
          > return name;
          > }
          >
          > and then you can
          >
          > writeFile << * characterFile;[/color]

          What about the age?
          [color=blue]
          >
          >[color=green]
          >>
          >> writeFile.close ();
          >>
          >> }[/color][/color]

          Comment

          • Fabio

            #6
            Re: Saving a binary file help.


            "G-Factor" <gezza@iprimus. com.au> wrote in message
            news:3f09431a_1 @news.iprimus.c om.au...[color=blue]
            >[color=green]
            > > And what about the 'age' field ?
            > > I guess G-Factor wanted to save both 'age' and 'name' field.
            > >
            > > Fabio[/color]
            >
            > Yes, I want to save the entire class.
            >[/color]
            IMHO you can overload the operator << to save object data into file
            (serialize) and >> operator to load object data from file (deserialize)
            I wrote a simple example without error-checks so please take it as a pure
            sample.

            class character
            {
            public:
            character() {};
            character(std:: string charName) : name(charName) {}
            virtual ~character() {};

            std::string getCharName();

            private:
            friend std::ostream& operator << (std::ostream& s, const character& c);
            friend std::istream& operator >> (std::istream& s, character& c);

            std::string name;
            int age;
            };

            std::ostream& operator << (std::ostream& s, const character& c)
            {
            std::string::si ze_type stype = c.name.length() ;
            s.write((char*) &stype, sizeof(stype) );
            s.write(c.name. c_str(),c.name. length());
            s.write((char*) &c.age,sizeof(c .age));
            return s;
            }

            std::istream& operator >> (std::istream& s, character& c)
            {
            std::string::si ze_type stype = 0;
            s.read((char*) &stype, sizeof(stype) );
            char* pstr = new(std::nothro w) char[stype+1];
            s.read(pstr,sty pe);
            pstr[stype] = '\0';
            c.name = pstr;
            delete [] pstr;

            s.read((char*) &c.age,sizeof(c .age));
            return s;
            }

            int main()
            {
            std::ofstream ofile("game.dat ", std::ios_base:: out | std::ios_base:: trunc
            | std::ios::binar y);

            character c1("pippo");

            ofile << c1;
            ofile.close();

            std::ifstream ifile("game.dat ", std::ios_base:: in | std::ios::binar y);

            character c2;

            ifile >> c2;
            ifile.close();

            return 0;
            }

            I hope this simple code can help you.
            Fabio


            Comment

            • Fabio

              #7
              Re: Saving a binary file help.


              "Thomas Matthews" <thomas_matthew s@sbcglobal.net > wrote in message
              news:3F097F5D.6 090803@sbcgloba l.net...[color=blue]
              > 3. The binary format of the fields _may_ not be portable across
              > platforms or compiler implementations .[/color]

              So why, in your sample, don't you use any signature to identify memory model
              (little-endian or big-endian) while saving the integer field ?
              [color=blue]
              > 4. DO NOT USE OPERATOR<<. The operator is for formatted data,
              > not unformatted binary data.[/color]

              Thanks. I forgot that important point.

              Fabio


              Comment

              • Thomas Matthews

                #8
                Re: Saving a binary file help.

                Fabio wrote:[color=blue]
                > "Thomas Matthews" <thomas_matthew s@sbcglobal.net > wrote in message
                > news:3F097F5D.6 090803@sbcgloba l.net...
                >[color=green]
                >>3. The binary format of the fields _may_ not be portable across
                >> platforms or compiler implementations .[/color]
                >
                >
                > So why, in your sample, don't you use any signature to identify memory model
                > (little-endian or big-endian) while saving the integer field ?[/color]

                Imagine the size of adding an additional byte for every multibyte
                value (not including text).

                One could save the Endianess at the beginning of the file.
                That would be one flag instead of many.

                If you need to deal with Endianism, you could read the value
                into a buffer then pass the buffer through an endianism filter.
                The filter would swap bytes if necessary. The filter could
                be activated based on the header information.

                Endianess is no problem if and only if the file stays on
                the same platform.

                If the file is to be used across platforms, try using
                ASCII formatted numbers. Most systems can convert an ASCII
                number into native format. The C++ language even has
                facilities for this.

                Otherwise one has to flag the platform specifics such as
                endianess, bits per value and floating point format.

                Also, my sample was not complete, but enough to give
                you an idea and basis to build upon. I didn't supply
                code for buffer support and inheritance.
                [color=blue]
                >
                >[color=green]
                >>4. DO NOT USE OPERATOR<<. The operator is for formatted data,
                >> not unformatted binary data.[/color]
                >
                >
                > Thanks. I forgot that important point.
                >
                > Fabio
                >[/color]
                --
                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

                Comment

                Working...