I built a small piece of code which creates some objects, read the objects already saved in a file and appends new objects if they don't belong to the file records. When I run the app the first time the objects are appended to the file. The second time I run the app, I get a segmentation fault
when I try to print or save the object on a list. The problem happens in the function openFileRead()
. The temporary Player
object is created from the default constructor and I try to assign to it the values of the file stream.read((char *) &p,sizeof(Player))
and then save it on the list PlayerFileList.push_back(p);
. Here the fault happens. The object isn't correctly assigned to the record in the file, I suppose, since if I try to send it's values to stdout
, before saving it in the list, I also get the fault. I think that the operator==
isn't working. I didn't overloaded this operator since I don't have static or pointers allocated members in Player
object. So, I don't understand this weird the fault. The code is:
header:
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
class Player
{
private:
string PlayerName;
int PlayerScore;
public:
Player();
Player(string name, int s);
~Player() {};
string getPlayerName() {return PlayerName;}
int getPlayerScore() {return PlayerScore;}
void setPlayerName(string name){PlayerName = name;}
void setPlayerScore(int score){PlayerScore = score;}
bool operator!=(const Player &) const;
bool operator==( const Player &) const;
};
class Game
{
private:
Player NewPlayer;
int NPlayers;
int NFilePlayers;
vector <Player> PlayerList;
fstream stream2;
ifstream stream;
vector <Player> PlayerFileList;
public:
Game();
~Game();
void setNewPlayer(string, int);
void resizePlayerList();
void PrintList();
void openFileRead();
void openFileWrite();
void closeFile();
void writeToFile();
friend std::ostream& operator<< (std::ostream&, Player);
};
class file:
#include <iostream>
#include <string>
#include <cstring>
#include <memory>
#include <fstream>
#include <algorithm>
#include <vector>
#include "I.h"
using namespace std;
Player::Player()
{
PlayerName = "No Name";
PlayerScore = 0;
}
Player::Player(string name, int s)
{
PlayerName = name;
PlayerScore = s;
}
bool Player::operator==(const Player &player) const
{
return( (PlayerName == player.PlayerName) && ( PlayerScore == player.PlayerScore) );
}
bool Player::operator!=(const Player &player) const
{
cout << PlayerName << player.PlayerName << " "<< PlayerScore << player.PlayerScore << endl;
return( (PlayerName != player.PlayerName) || (PlayerScore != player.PlayerScore) );
}
std::ostream& operator<< (std::ostream& stream, Player player)
{
stream << player.getPlayerName() << " " << player.getPlayerScore() << endl;
return stream;
}
Game::Game()
{
NPlayers = 0;
};
Game::~Game() {};
void Game::setNewPlayer(string str, int scr)
{
NewPlayer = Player(str, scr);
resizePlayerList();
}
void Game::resizePlayerList() {
if(NewPlayer.getPlayerName() != "No Name")
{
PlayerList.push_back (NewPlayer);
NPlayers++;
}
}
void Game::PrintList()
{
for(int i= 0; i < NPlayers; i++)
{
cout << PlayerList[i] << endl;
}
}
void Game::openFileWrite()
{
stream2.open("Players.dat", ios::app | ios::in | ios::binary);
if (!stream2)
{
cerr << "File could not be opened to write" << endl;
exit(EXIT_FAILURE);
}
}
void Game::openFileRead()
{
stream.open("Players.dat", ios::in | ios::out | ios::app |ios::binary );
if (!stream)
{
cerr << "File could not be opened to read" << endl;
exit(EXIT_FAILURE);
}
stream.seekg (0, stream.end);
int length = stream.tellg()/sizeof(Player);
stream.seekg (0, stream.beg);
Player p;
for(int i= 0; i < length; i++)
{
stream.read((char *) &p,sizeof(Player));
PlayerFileList.push_back(p);
}
NFilePlayers = PlayerFileList.size();
for(int i= 0; i <NFilePlayers; i++)
{
cout << PlayerFileList[i] << endl;
}
stream.close();
}
void Game::writeToFile()
{
vector <Player> vec;
Player p;
for (int i=0; i < NPlayers; i++)
{
if (std::find(PlayerFileList.begin(), PlayerFileList.end(), PlayerList[i]) == PlayerFileList.end())
{
stream2.write((const char *)&PlayerList[i],sizeof(Player));
}
}
}
main:
#include <iostream>
#include <string>
#include "I.h"
using namespace std;
int main()
{
Game NewGame;
NewGame.openFileRead();
NewGame.setNewPlayer("Peter",20);
NewGame.setNewPlayer("Someone Someone",30);
NewGame.setNewPlayer("Someone else",40);
NewGame.PrintList();
NewGame.openFileWrite();
NewGame.writeToFile();
return 0;
}
If the problem is related with the std::string
class and I still want to write the file in binary mode
since each field object can contain several member data (I just used 2 for illustration) how can I do that? No book explains that, at least, none I ever read.
Aucun commentaire:
Enregistrer un commentaire