only on DEBUG this code crashes

Started by
12 comments, last by EvilNando 12 years, 9 months ago

should I use fixed char arrays instead or is there an actual way of reading std::strings of variable size using ifstream

The first link when I throw "C++ serialization" into google.
Advertisement
You can use std::string, all you have to do is writing each variable in GameMonster one at a time

#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <fstream>

using namespace std;

class GameMonster
{
public:
string Name;
int Hp;
int Damage;

GameMonster() { Name = ""; Hp = 0; Damage = 0; }
GameMonster(string name, int hp, int dmg) { Name = name; Hp = hp; Damage = dmg; }
};



int main()
{
GameMonster _monster;
GameMonster _monsters[3] = { GameMonster("Troll", 50, 20), GameMonster("Skeleton", 10, 5), GameMonster("Rat", 5, 1) };

ofstream _file("GameData.dat", ios::binary);

for (int i = 0; i < 3; i++)
{
int nameLength = _monsters.Name.size();
_file.write((char*)&nameLength, sizeof(int));
_file.write(_monsters.Name.c_str(), _monsters.Name.size());
_file.write((char*)&_monsters.Hp, sizeof(int));
_file.write((char*)&_monsters.Damage, sizeof(int));
}


_file.seekp(0, ios::end);
cout<<"size of GameData.dat "<<_file.tellp()<<" bytes"<<endl<<endl;

_file.close();


ifstream _file_input("GameData.dat", ios::binary);
for (int _idx = 0; _idx < 3; _idx++)
{
cout<<"size of Monster "<<sizeof(GameMonster)<<" ";
cout<<"current seek pointer position :"<<_file_input.tellg()<<endl;

int nameLength;
_file_input.read((char*)&nameLength, sizeof(int));
_monster.Name.resize(nameLength);
_file_input.read(&_monster.Name[0], nameLength);
_file_input.read((char*)&_monster.Hp, sizeof(int));
_file_input.read((char*)&_monster.Damage, sizeof(int));

cout<<_monster.Damage<<" "<<_monster.Hp<<" "<<_monster.Name<<endl;
}

_file_input.close();

cout<<"\nPress a key"<<endl;
getchar();
}
To make it easier, consider writing helper functions:

// Some IO Helper header
namespace detail
{
template<typename Type>
std::istream &readPOD(std::istream &in, Type &instance)
{
char *pointer = reinterpret_cast<char *>(&instance);
return in.read(pointer, sizeof(instance));
}

template<typename Type>
std::ostream &writePOD(std::ostream &out, const Type &instance)
{
const char *pointer = reinterpret_cast<const char *>(&instance);
return out.write(pointer, sizeof(instance);
}
}

std::istream &read(std::istream &in, int &i)
{
return detail::readPOD(in, i);
}

std::istream &read(std::istream &in, std::string &s)
{
int count;
if(read(in, count))
{
vector<char> data;
data.resize(count);
if(in.read(&data.front(), count))
{
s.assign(data.begin(), data.end());
}
}
return in;
}

std::istream &write(std::ostream &out, int i)
{
return detail::write(out, i);
}

std::istream &write(std::ostream &out, const std::string &s)
{
int n = s.size();
write(n);
return out.write(s.c_str(), n);
}

// Monster

void read(std::istream &in, Monster &monster)
{
if(!(read(monster.Hp) && read(monster.Damage) && read(monster.Name)))
{
// error handling?
}
}

void write(std::ostream &out, const Monster &monster)
{
if(!(write(monster.Hp) && write(monster.Damage) && write(monster.Name)))
{
// error handling?
}
}
Thanks

This topic is closed to new replies.

Advertisement