struct speichern/laden ->Fehler!



  • Dragonfire schrieb:

    Wie sähen die Memberfunktionen aus?

    so etwa

    ostream& Info::write(ostream& out) const
    {
        int strsize =  spiel.Length();
        out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize));
        out.write(spiel().c_str(), strsize+1);
    // usw.
    }
    
    istream& Info::read(istream&  in)
    {
        int strsize;
        in.read(reinterpret_cast<char*>(&strsize), sizeof(strsize));
        char* tstr = new char[strsize+1];
        in.read(tstr, strsize+1);
        delete[] tstr;
    // usw.
    


  • Da must du dir schon selber einen Kopf machen. Da du ja mit den AnsiStrings keine reine PODs mehr hast gibt es kein einfaches binäres Format mehr.

    Die AnsiString müssen nicht sein, man kann ja auch char[] verwenden, nötigenfalls mit begrenzung, z.B. char[255].

    Braunsteins Verbesserung zeigt den aktuellen C++ Standard

    Aha 😃

    Du must die Op-Deklaration (und nur die Deklaration, nicht die Implementatio) auch in die Unit.h schreiben.

    Hab ich gemacht (ich dummi^^).
    Nun bekomm ich folgende Meldung:

    [C++ Fehler] CraGine.h(42): E2080 'Unit::operator <<(ostream,const Info)' muß mit einem Parameter deklariert werden

    thx nochmal für die Mühen 😃

    [EDIT]Oh zuspät...Danke 😃 , ich probiers gleich mal aus.[/EDIT]



  • Die Deklaration sollte so aussehen

    std::ostream& operator<<(std::ostream& stream, const Info& info);
    

    Natürlich muß Info zu diesem Zeitpunkt bekannt sein. Es ist sowieso am besten die Operation im selben headerfile wie die Klasse zu deklarieren.



  • so bin jetzt soweit:

    #unit.cpp#

    ...
    ostream& Info::write(ostream& out) const
    { 
        int strsize =  spiel.Length(); 
        out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize));
        out.write(spiel().c_str(), strsize+1);
    
        strsize = version.Length();
        out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize));
        out.write(version().c_str(), strsize+1);
    
        strsize = typ.Length();
        out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize));
        out.write(typ().c_str(), strsize+1);
    
        strsize = autor.Length();
        out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize));
        out.write(autor().c_str(), strsize+1);
    
        strsize = beschreibung.Length();
        out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize));
        out.write(beschreibung().c_str(), strsize+1);
    
        strsize = erweiterung.Length();
        out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize));
        out.write(erweiterung().c_str(), strsize+1);
    
        strsize = sizeof(groesse);
        out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize));
        out.write(groesse, strsize+1);
    }
    

    Bei:

    istream& Info::read(istream&  in)
    {
        int strsize;
        in.read(reinterpret_cast<char*>(&strsize), sizeof(strsize));
        char* tstr = new char[strsize+1];
        in.read(tstr, strsize+1);
        delete[] tstr;
    // usw.    
    }
    

    Was bedeutet/was ist hier: tstr?

    #unit.h#

    ...
    ostream& write(ostream&) const;
    istream& read(istream&);
    

    trotzdem kennt er die Methoden in der cpp datei nicht...



  • tstr ist nur ein temporärer String. Ich hatte da vergessen den eingelesenen Inhalt zu übertragen.
    So wäre es richtig.

    istream& Info::read(istream&  in)
    {
        int strsize;
        in.read(reinterpret_cast<char*>(&strsize), sizeof(strsize));
        char* tstr = new char[strsize+1];
        in.read(tstr, strsize+1);
        spiel = tstr;
        delete[] tstr;
    // usw.    
    }
    

    Beim write oben müssen die Klammern nach spiel usw. weg. (auch mein Fehler).
    Die Deklarationen von read und write gehören in deine Info-Klasse.
    Bitte versuche mal zu verstehen was das bedeutet. Dann mußt du auch nicht mehr so viel fragen und findest deartige Fehler selber.



  • Gut 😃 Mach ich.

    Nur bin ich im speichern auf Festplatte in C++ nicht so fit^^.

    Nur habe ich immer noch die Fehlermeldung:

    [C++ Fehler] Unit.cpp(222): E2015 Mehrdeutigkeit zwischen '_STL::basic_istream<char,_STL::char_traits<char> >::operator >>(bool &)' und '_STL::basic_istream<char,_STL::char_traits<char> >::operator >>(void * &)'



  • Poste mal den relevanten Code. Du willst anscheinend immer noch einen Zeiger auf Info ausgeben.
    Lies dir evtl. noch das hier aus der C++ FAQ durch
    Ströme und Dateien in C++



  • Gut:

    Unit.h:

    //---------------------------------------------------------------------------
    
    #ifndef UnitH
    #define UnitH
    #include <fstream>
    #include <system>
    //---------------------------------------------------------------------------
    struct Info
    {
    AnsiString  spiel;
    AnsiString  version;
    AnsiString  typ;
    AnsiString  autor;
    int  groesse;
    AnsiString  beschreibung;
    AnsiString  erweiterung;
    
    ostream& write(ostream&) const;
    istream& read(istream&);
    };
    
    class Loesung
    {
      private:
    char       *datei;
    Info       *info;
    AnsiString  version;
    void        extendInfoArray();
    void        reduceInfoArray();
    int         loesungen;
    int         getInfoArrayLength();
      public:
                Loesung();
               ~Loesung();
    int         einlesen(char*);
    int         speichern(char*);
    Info        getInfos(int);
    AnsiString  getVersion();
    void        verifizieren(AnsiString, AnsiString, AnsiString, AnsiString, AnsiString);
    int         getLoesungAnzahl();
    int         saveInfoToFile(char*);
    int         loadInfoFromFile(char*);
    int         loadLoesungFromArchive(char*,int);
    AnsiString         test();
    };
    //---------------------------------------------------------------------------
    #endif
    

    Unit.cpp:

    //---------------------------------------------------------------------------
    
    #pragma hdrstop
    
    #include <Unit>
    //---------------------------------------------------------------------------
    
    #pragma package(smart_init)
    //---------------------------------------------------------------------------
    
    Loesung::Loesung()
    {
      version = "0.4.9";
      info = new Info[1];
      loesungen = 0;
    }
    //---------------------------------------------------------------------------
    
    //Gibt 0 zurück wenn ein Fehler auftrat, 1 wenn nicht
    int Loesung::einlesen(char *datei)
    {
    //----Stream-initialisieren----
      ifstream ifl(datei, ios::in|ios::binary);
    //----Fehler?----
      if(!ifl)
      {
        return 0;
      }
    //----Länge-bestimmen----
      unsigned int ende;
      ifl.seekg(0, ios::end);
      ende = ifl.tellg();
      ifl.seekg(0, ios::beg);
    //----Array-initialisieren----
      delete datei;
      datei = new char[ende];
    //----Daten-einlesen----
      ifl.read((char*)datei, ende);
    //----Stream-schließen----
      ifl.close();
    //----Info-vorbereiten----
    if(loesungen > 0)
    {
      extendInfoArray();
    }
    //----Info-setzen----
      info[loesungen].groesse = ende;
      AnsiString erw = (AnsiString)datei;
      int punkt = erw.LastDelimiter(".");
      erw = erw.SubString(punkt, erw.Length()-punkt);
      info[loesungen].erweiterung = erw.c_str();
    //----Alles-OK----
      return 1;
    }
    //---------------------------------------------------------------------------
    
    //Gibt 0 zurück wenn ein Fehler auftrat, 1 wenn nicht
    int Loesung::speichern(char *datei)
    {
    //----Stream-initialisieren----
      ofstream ofl(datei, ios::out|ios::binary);
    //----Fehler?----
      if(!ofl)
      {
        return 0;
    
      }
    //----Zeiger-auf-das-Ende-richten-zum-anhängen----
      ofl.seekp(0, ios::end);
    //----Schreiben----
      ofl.write((char*)datei, info[loesungen].groesse);
    //----Stream-schließen----
      ofl.close();
    //----Eine-Loesung-mehr----
      loesungen ++;
    //----Alles-OK----
      return 1;
    }
    //---------------------------------------------------------------------------
    
    Info Loesung::getInfos(int n)
    {
      return info[n];
    }
    //---------------------------------------------------------------------------
    
    AnsiString Loesung::getVersion()
    {
      return version;
    }
    //---------------------------------------------------------------------------
    
    void Loesung::verifizieren(AnsiString sp, AnsiString ve, AnsiString ty, AnsiString au, AnsiString be)
    {
      info[loesungen].spiel = sp.c_str();
      info[loesungen].version = ve.c_str();
      info[loesungen].typ = ty.c_str();
      info[loesungen].autor = au.c_str();
      info[loesungen].beschreibung  = be.c_str();
    }
    //---------------------------------------------------------------------------
    
    Loesung::~Loesung()
    {
    }
    //---------------------------------------------------------------------------
    
    int Loesung::getLoesungAnzahl()
    {
      return loesungen;
    }
    //---------------------------------------------------------------------------
    
    void Loesung::extendInfoArray()
    {
      if(loesungen == 0)
      {
        return;
      }
    
      Info *dummy = new Info[loesungen+1];
    
      for(int i; i < loesungen; i ++)
      {
        dummy[i].spiel = info[i].spiel;
        dummy[i].version = info[i].version;
        dummy[i].typ = info[i].typ;
        dummy[i].autor = info[i].autor;
        dummy[i].groesse = info[i].groesse;
        dummy[i].beschreibung = info[i].beschreibung;
        dummy[i].erweiterung = info[i].erweiterung;
      }
    
      info = new Info[loesungen+1];
    
      for(int i; i < loesungen; i ++)
      {
        info[i].spiel = dummy[i].spiel;
        info[i].version = dummy[i].version;
        info[i].typ = dummy[i].typ;
        info[i].autor = dummy[i].autor;
        info[i].groesse = dummy[i].groesse;
        info[i].beschreibung = dummy[i].beschreibung;
        info[i].erweiterung = dummy[i].erweiterung;
      }
    }
    //---------------------------------------------------------------------------
    
    void Loesung::reduceInfoArray()
    {
      if(loesungen == 0)
      {
        return;
      }
    
      Info *dummy = new Info[loesungen-1];
    
      for(int i; i < loesungen; i ++)
      {
        dummy[i].spiel = info[i].spiel;
        dummy[i].version = info[i].version;
        dummy[i].typ = info[i].typ;
        dummy[i].autor = info[i].autor;
        dummy[i].groesse = info[i].groesse;
        dummy[i].beschreibung = info[i].beschreibung;
      }
    
      info = new Info[loesungen-1];
    
      for(int i; i < loesungen; i ++)
      {
        info[i].spiel = dummy[i].spiel;
        info[i].version = dummy[i].version;
        info[i].typ = dummy[i].typ;
        info[i].autor = dummy[i].autor;
        info[i].groesse = dummy[i].groesse;
        info[i].beschreibung = dummy[i].beschreibung;
      }
    
      loesungen --;
    }
    //---------------------------------------------------------------------------
    
    int Loesung::saveInfoToFile(char *datei)
    {
    //----Stream-initialisieren----
      ofstream ofl(datei, ios::out|ios::binary);
    //----Fehler?----
      if(!ofl)
      {
        return 0;
    
      }
    //----Schreiben----
      //ofl.write((char*)info, sizeof(*info));
      ofl << info;
    //----Stream-schließen----
      ofl.close();
    //----Alles-OK----
      return 1;
    }
    //---------------------------------------------------------------------------
    
    int Loesung::loadInfoFromFile(char *datei)
    {
    //----Stream-initialisieren----
      ifstream ifl(datei, ios::in|ios::binary);
    //----Fehler?----
      if(!ifl)
      {
        return 0;
      }
    //----Länge-bestimmen----
      unsigned int ende;
      ifl.seekg(0, ios::end);
      ende = ifl.tellg();
      ifl.seekg(0, ios::beg);
    //----Daten-einlesen----
      //info = new Info[ende/sizeof(Info)];
      //ifl.read((char*)info, ende);
      ifl >> info;
    //----Stream-schließen----
      ifl.close();
    //----Loesungen-setzen----
      loesungen = getInfoArrayLength();
    //----Alles-OK----
      return 1;
    }
    //---------------------------------------------------------------------------
    
    int Loesung::loadLoesungFromArchive(char *datei, int n)
    {
      int gr = 0;
    
      for(int i = 0; i < n-1; i ++)
      {
        gr += info[i].groesse;
      }
    
    //----Stream-initialisieren----
      ifstream ifl(datei, ios::in|ios::binary);
    //----Fehler?----
      if(!ifl)
      {
        return 0;
      }
    //----Länge-bestimmen----
      unsigned int ende;
      ifl.seekg(0, ios::end);
      ende = ifl.tellg();
      ifl.seekg(0, gr);
    //----Array-initialisieren----
      delete datei;
      datei = new char[ende-gr];
    //----Daten-einlesen----
      ifl.read((char*)datei, ende-gr);
    //----Stream-schließen----
      ifl.close();
    //----Alles-OK----
      return 1;
    }
    //---------------------------------------------------------------------------
    
    int Loesung::getInfoArrayLength()
    {
      return sizeof(*info)/sizeof(Info);
    }
    //---------------------------------------------------------------------------
    
    AnsiString Loesung::test()
    {
    
    }
    //---------------------------------------------------------------------------
    
    istream& read(istream&  in)
    {
        int strsize;
        in.read(reinterpret_cast<char*>(&strsize), sizeof(strsize));
        char* tstr = new char[strsize+1];
        in.read(tstr, strsize+1);
        spiel = tstr;
        delete[] tstr;
    
        strsize;
        in.read(reinterpret_cast<char*>(&strsize), sizeof(strsize));
        tstr = new char[strsize+1];
        in.read(tstr, strsize+1);
        version = tstr;
        delete[] tstr;
    
        strsize;
        in.read(reinterpret_cast<char*>(&strsize), sizeof(strsize));
        tstr = new char[strsize+1];
        in.read(tstr, strsize+1);
        typ = tstr;
        delete[] tstr;
    
        strsize;
        in.read(reinterpret_cast<char*>(&strsize), sizeof(strsize));
        tstr = new char[strsize+1];
        in.read(tstr, strsize+1);
        autor = tstr;
        delete[] tstr;
    
        strsize;
        in.read(reinterpret_cast<char*>(&strsize), sizeof(strsize));
        tstr = new char[strsize+1];
        in.read(tstr, strsize+1);
        beschreibung = tstr;
        delete[] tstr;
    
        strsize;
        in.read(reinterpret_cast<char*>(&strsize), sizeof(strsize));
        tstr = new char[strsize+1];
        in.read(tstr, strsize+1);
        erweiterung = tstr;
        delete[] tstr;
    
        strsize;
        in.read(reinterpret_cast<char*>(&strsize), sizeof(strsize));
        int val;
        in.read((char*)val, strsize+1);
        groesse = val;
    }
    //---------------------------------------------------------------------------
    
    ostream& write(ostream& out) const
    {
        int strsize =  spiel.Length(); 
        out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize));
        out.write(spiel.c_str(), strsize+1);
    
        strsize = version.Length();
        out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize));
        out.write(version.c_str(), strsize+1);
    
        strsize = typ.Length();
        out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize));
        out.write(typ.c_str(), strsize+1);
    
        strsize = autor.Length();
        out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize));
        out.write(autor.c_str(), strsize+1);
    
        strsize = beschreibung.Length();
        out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize));
        out.write(beschreibung.c_str(), strsize+1);
    
        strsize = erweiterung.Length();
        out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize));
        out.write(erweiterung.c_str(), strsize+1);
    
        strsize = sizeof(groesse);
        out.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize));
        out.write(groesse, strsize+1);
    }
    //---------------------------------------------------------------------------
    


  • Ok,

    mach mal aus #include <Unit> besser #include "Unit.h"
    Du sollst das .h nicht bei allen Include weglassen sondern nur bei den Standardheadern (system ist auch kein Standardheader).

    2. Deklaration der Schreib/Lesefunktionen sollte so aussehen

    std::ostream& write(std::ostream&) const;
    std::istream& read(std::istream&);
    

    Du mußt den namespace std in den Headerdateien immer mit angeben.

    3. Bei den Definitionen dieser Funktionen hast du den Klassenscope vergessen.
    also

    istream& Info::read(istream&  in)
    

    4. saveInfoToFile ist falsch
    so wird es besser

    bool Loesung::saveInfoToFile(char *datei)
    {
    //----Stream-initialisieren----
      ofstream ofl(datei, ios::out|ios::binary);
    //----Fehler?----
      if(!ofl) return false;
    //----Schreiben----
      info[loesungen].write(ofl); // write ist doch eine Memberfunktion von Info
      return true;
    }
    

    5. das hier funktioniert nicht

    int Loesung::getInfoArrayLength()
    {
      return sizeof(*info)/sizeof(Info);
    }
    

    Merke dir lieber die Größe deines Arrays in einer membervariablen von Loesung und gib die dann zurück.

    6. Was sollen in verifizieren die vielen c_str()?

    7. Überarbeite einlesen noch mal. da ist vieles faul drin. Warum übergibst du den Dateinamen als char* ? Nimm lieber überall AnsiString.

    8. Weiter habe ich jetzt nicht geschaut, da ich jetzt langsam Feierabend machen werde.

    Ciao



  • so habs geschafft, Danke! 😃


Anmelden zum Antworten