0

the IDE i'm using (visual studio 2012) doesn't show any errors or warnings, but i'm basicly trying to write binary data to a file called wizdata.bin and I have declared a few objects of my Wizard class. the Wizard class has few functions with 4 member variables ( 1 string and 3 ints). When I call the function in Wizard class called "save" the console program stops working, but it does manage to write the Wizard class member variable name which is a string. After that it fails to write any of the ints in the class. So the question is what am I doing wrong with trying to write ints to a binary file? the part that is commended in Wizard.cpp is causing the crash.

heres my code files:

Wizard.h:

    #ifndef WIZARD_H
    #define WIZARD_H

    #include <string>
    #include <fstream>

    class Wizard
    {
    public:
        Wizard();
        Wizard( std::string name, int hp, int mp, int armor );

        void print();

        void save( std::ofstream& outFile );
        void load( std::ifstream& inFile );

    private:
        std::string name;
        int hitPoints;
        int magicPoints;
        int armor;
    };

    #endif

Wizard.cpp:

    #include "Wizard.h"
    #include <iostream>
    using namespace std;

    Wizard::Wizard()
    {
        name = "Default";
        hitPoints = 0;
        magicPoints = 0;
        armor = 0;
    }

    Wizard::Wizard( string name, int hp, int mp, int armor )
    {
        this->name = name;
        hitPoints = hp;
        magicPoints = mp;
        this->armor = armor;
    }

    void Wizard::print()
    {
        cout << "Name= " << name << endl;
        cout << "HP= " << hitPoints << endl;
        cout << "MP= " << magicPoints << endl;
        cout << "Armor= " << armor << endl;
        cout << endl;
    }

    void Wizard::save( ofstream& outFile )
    {
        outFile.write( name.c_str(), name.size() );
        //outFile.write( (char*)hitPoints, sizeof(hitPoints) );
        //outFile.write( (char*)magicPoints, sizeof(magicPoints) );
        //outFile.write( (char*)armor, sizeof(armor) );
    }

    void Wizard::load( ifstream& inFile )
    {
        inFile.read( (char*)name.c_str(), name.size() );
        inFile.read( (char*)&hitPoints, sizeof(hitPoints) );
        inFile.read( (char*)&magicPoints, sizeof(magicPoints) );
        inFile.read( (char*)&armor, sizeof(armor) );
    }

and Main.cpp:

    #include "Wizard.h"
    using namespace std;

    int main()
    {
        Wizard wiz0( "Gandalf", 25, 100, 10 );
        Wizard wiz1( "Loki", 50, 150, 12 );
        Wizard wiz2( "Magius", 10, 75, 6 );

        ofstream outFile;
        outFile.open( "wizdata.bin", ios_base::binary );

        if( outFile )
        {
            wiz0.save( outFile );
            wiz1.save( outFile );
            wiz2.save( outFile );

            outFile.close();
        }

        return 0;
    }

this is the "Main.cpp" of my second console app that loads the data:

    #include "Wizard.h"
    #include <iostream>
    using namespace std;

    int main()
    {
        Wizard wiz0;
        Wizard wiz1;
        Wizard wiz2;

        cout << "BEFORE LOADING..." << endl;
        wiz0.print();
        wiz1.print();
        wiz2.print();

        ifstream inFile;
        inFile.open( "wizdata.bin", ios_base::binary );

        if( inFile )
        {
            wiz0.load( inFile );
            wiz1.load( inFile );
            wiz2.load( inFile );

            inFile.close();
        }

        cout << "AFTER LOADING..." << endl;
        wiz0.print();
        wiz1.print();
        wiz2.print();

        return 0;
    }

after loading the data this these are the values: Name: Gandalf HP: 25 MP: 100 Armor: 10

Name: Loki2 HP: 38400 MP: 3072 Armor: 1734429952

Name: ius HP: 75 MP: 6 Armor: 0

2 Answers2

1

Short answer:

Use the shift operator '<<' instead of write ().

Little bit longer answer:

The problem is the cast. (char *)number interprets the number as a pointer, which of course cannot point to anything meaningful.

steffen
  • 8,572
  • 11
  • 52
  • 90
0

The first argument of write should be a pointer to the data you want to write. So try this:

outFile.write( (char*)&hitPoints, sizeof(hitPoints) );
jdc
  • 319
  • 2
  • 5
  • This fixed the problem, but now I'm trying to load the saved data in a different console app. It does load the data, but after the first Wizard class the data seems to mess up showing that Wizard loki has over 17000 hitPoints, magicPoints and armor. Any idea why the data doesn't load properly? I updated the load function. – Ebbe Suominen Nov 23 '13 at 20:00
  • I think you should do `outFile.write( name.c_str(), name.size()+1 );` because the c_str() function adds the null character at the end of the string. – jdc Nov 23 '13 at 20:14
  • Thanks for the quick help you provided I now managed to find the cause of the problem. When I save string data in binary format to a file I also need to save the size of the string as an int to the file before the string so that I know how many bytes I need to take for the string. – Ebbe Suominen Nov 24 '13 at 10:01