2017-03-11 2 views
1

Ich versuche, Daten in eine Binärdatei zu speichern und zu laden, damit ich den Inhalt später abrufen kann. Der Code, den ich verwendet habe, wenn jedes Datenelement dieselbe Größe hatte, aber mit diesen Klassendaten funktioniert es nicht. Ich habe einige Anpassungen vorgenommen, um dies zu beheben, indem ich eine Datengrößenvariable speicherte. Dies hat jedoch auch nicht funktioniert. Hier ist meine Klasse:Speichern und Laden von Klassendaten in einer Binärdatei in C++

class Player 
{ 
public: 
    Player(); 
    Player(int playerID, std::string name, std::string country, int startYear, std::vector<int> rankPerYear); 
    ~Player(); 

    int getRank() { return rank; } 

private: 
    int playerID; 
    std::string name; 
    std::string country; 
    int rankingPts; 
    int rank; 
    int startYear; 
    std::vector<int> rankPerYear; 
    Schedule schedule; 
    PlayerStats playerStats; 
}; 

Und hier meine Last und speichern Funktionen:

void GameData::saveGame(std::string fileName) 
{ 
    std::ofstream file; 
    fileName += ".bin"; 
    file.open(fileName.c_str(), std::ios::binary | std::ios::out); 

    size_t tempSize = 0; 

    for (int i = 0; i < players.size(); i++) { 
     tempSize = sizeof(players[i]); 
     file.write((char*)&tempSize, sizeof(size_t)); 

     file.write((char*)&players[i], tempSize); 
    } 

} 

void GameData::loadGame(std::string fileName) 
{ 
    players.clear(); 
    fileName += ".bin"; 
    if (std::ifstream(fileName)) { 
     std::ifstream file; 
     file.open(fileName.c_str(), std::ios::binary | std::ios::in); 
     if (!file.is_open()) { 
      std::cout << "Error while opening the file"; 
     } 
     else { 
      std::string temp; 
      int location = 0; 
      size_t tempSize = 0; 
      Player player; 
      while (std::getline(file, temp)) { 
       file.seekg(location, std::ios::beg); 
       file.read((char*)&tempSize, sizeof(size_t)); 
       file.seekg(sizeof(size_t) + location, std::ios::beg); 
       file.read((char*)&player, tempSize); 
       players.push_back(player); 
       location += sizeof(size_t) + tempSize; 
      } 
     } 
    } 
    else { 
     saveGame(fileName); 
    } 
} 

Ich bin der Spieler auf einen Vektor, der Spieler zu speichern. Wenn ich versuche, dies zu laufen bekomme ich den Fehler:

Exception thrown at 0x0F485097 (vcruntime140d.dll) in Ping Pong Manager.exe: 0xC0000005: Access violation reading location 0x081BCE20. 

Wenn diese Debuggen fand ich, dass es richtig einen Teil der Daten speichern würde, würde aber dann abstürzen, bevor es fertig. Ich weiß, dass es teilweise funktioniert. Ich habe viele verschiedene Dinge ausprobiert, kann aber mein Problem nicht erkennen. Danke für die Hilfe.

+1

Aus irgendeinem Grund diese fehlerhafte „Binärdatei Lesen/Schreiben“ Beispiele scheinen eine Epidemie hier auf SO zu sein. Dies ist zumindest der dritte heute mit den gleichen Fehlern und einer von vielen (wahrscheinlich Tausenden) von Beispielen insgesamt. Wenn Sie nicht C-Code schreiben oder mit C-kompatiblen Typen arbeiten, funktioniert das in C++ nicht korrekt. – PaulMcKenzie

+1

[Dieses Testprogramm] (http://ideone.com/Hkcbe4) bestimmt, ob 'Player' ein POD-Typ ist. Da es sich nicht um einen POD-Typ handelt, können Sie ihn nicht zum Lesen oder Schreiben verwenden, wie Sie es gerade tun. – PaulMcKenzie

+0

Zum Beispiel schrieb ich dieses früher http://stackoverflow.com/a/42729331/4581301. Es befasst sich hauptsächlich mit einer 'std :: string', berührt aber auch' std :: vector'. – user4581301

Antwort

4

Sie können STL-Container nicht direkt serialisieren, da sie Zeiger enthalten.

Der übliche Weg besteht darin, das Feld einzeln zu schreiben, wobei spezielle Methoden für Dinge verwendet werden, die Zeiger auf Heap enthalten.

Bitte beachten Sie eine Serialisierungsbibliothek, die den Code für Sie generiert. Hier ist eine Liste:

Boost.Serialization

Cap'n'Proto

FlatBuffers

+0

Welche Bibliothek würde ich am besten mit meiner derzeitigen Struktur von Klassen und Unterklassen verwenden? Boost scheint mit vielen verschiedenen Klassen sehr kompliziert und schwer zu implementieren. – jmbockhorst

Verwandte Themen