Probleme mit Binärdatei einlesen



  • Ich habe folgendes Problem. Ich habe eine Binärdatei, die eine Tabelle einer Tischtennisliga enthält. Folgende Datenstruktur (Klasse "Team") soll dafür verwendet werden:

    class Team
    {
    private: 
         std::string teamName; 
         int matchesPlayed; 
         int gamesWon; 
         int gamesLost; 
         int pointsWon; 
         int pointsLost; 
    }
    

    Mein Problem ist schon einmal: wie gehe ich in einer Binärdatei mit dem String um? Ich möchte ja eigentlich über die read-Funktion von istream direkt einen Datensatz aus der Datei einlesen. Dafür habe ich folgende Funktion geschrieben:

    bool Table::loadList(char * filename)
    {
    	ifstream fin(filename, ios::binary);
    	//exit program if ifstream cannot open file
    	if(!fin) {
    		cerr<<"File could not be opened!"<<endl; 
    		return false; 
    	}
    	while(!fin.eof()) {
    		Team *mannschaft; 
    		fin.read(reinterpret_cast<char*>(mannschaft), sizeof(Team)); 
    		if(!fin.fail())
    			Teamtable.push_back(*mannschaft);
    	}
    	fin.close();
    	return true; 
    }
    

    Es handelt sich hier um eine andere Klasse "Table", die die Teams in einem std::vector verwaltet. So funktioniert das aber leider nicht, das Programm macht nichts. Ich glaube, dass es am String liegt, aber ich weiß nicht genau, wie ich das Problem umgehen kann.
    Ich hoffe Ihr könnt mir helfen.



  • das mit dem string kann tatsächlich nicht funktionieren. string-objekte enthalten nur einen zeiger auf die eigentlichen string-daten. wenn du das string-objekt binär speicherst, dann speicherst du also nur den zeiger! und der ist nach dem laden natürlich in der regel nicht mehr gültig.

    am besten, du speicherst jeden wert einzeln. da der code ein bißchen lang werden kann, schreibst du am besten eine eigene speicher- und lade-methode für die klasse team.

    und noch was: die eof/fehler-behandlung ist nicht in ordnung. die abfrage erfolgt bei iostreams mit good(). und wenn good()==false, dann prüfe auf eof() oder bad(). außerdem muß die prüfung unmittelbar nach dem dateizugriff und nicht in der while-bedingung erfolgen:

    for(;;)
    {
      Team *mannschaft; 
      fin.read(reinterpret_cast<char*>(mannschaft), sizeof(Team)); 
      if(!fin.good()) break;
      Teamtable.push_back(*mannschaft);
    }
    
    if(!fin.eof() || fin.gcount()!=sizeof(Team)) // wenn status == bad oder fail
    {
      // fehlerbehandlung
    }
    

    PS: !fin.good() ist nicht das selbe wie fin.bad()!!!


Log in to reply