fstream, struct, speichern laden



  • hallo,

    habe wieder das problem wie damals, aber irgendwas stimmt bei meiner neuen Anwendung noch nicht...

    thx

    struct Kamera
    {
        int         minThrow;
        int         maxThrow;
        int         werteAnzahl;
        bool        StandardDecoder;
        bool        HighspeedDecoder;
        AnsiString  Linse;
        AnsiString  ExcelDatei;
        AnsiString  ID_StandardDecoder;
        AnsiString  ID_HighspeedDecoder;
        std::vector <int>    Throw;
        std::vector <double> Resolution;
        std::vector <double> Coverage;
        std::vector <double> MinElementPreferred_015;
        std::vector <double> MinElementAbsolute_015;
        std::vector <double> MinElementPreferred_1545;
        std::vector <double> MinElementAbsolute_1545;
        std::vector <double> MaxBeltSpeed_StandardDecoder;
        std::vector <double> MaxBeltSpeed_HighspeedDecoder;
    
        int getPositionByThrow(int thr)
        {
          for(int i = 0; i < werteAnzahl; i ++)
          {
            if( Throw[i] == thr ) { return i; }
          }
    
        return -1;
        }
    
        bool saveToFile(AnsiString pfad, AnsiString endung)
        {
          ofstream ofl((pfad + "." + endung).c_str(), ios::out|ios::binary);
    
          if(!ofl)
          {
            return false;
          }
    
          ofl.write(reinterpret_cast<const char*>(&minThrow), sizeof(int));
          ofl.write(reinterpret_cast<const char*>(&maxThrow), sizeof(int));
          ofl.write(reinterpret_cast<const char*>(&werteAnzahl), sizeof(int));
    
          int sd = (int)StandardDecoder;
          int hd = (int)HighspeedDecoder;
          ofl.write(reinterpret_cast<const char*>(&sd), sizeof(int));
          ofl.write(reinterpret_cast<const char*>(&hd), sizeof(int));
    
          int strsize = Linse.Length();
          ofl.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize));
          ofl.write(Linse.c_str(), strsize+1);
    
          strsize = ExcelDatei.Length();
          ofl.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize));
          ofl.write(ExcelDatei.c_str(), strsize+1);
    
          strsize = ID_StandardDecoder.Length();
          ofl.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize));
          ofl.write(ID_StandardDecoder.c_str(), strsize+1);
    
          strsize = ID_HighspeedDecoder.Length();
          ofl.write(reinterpret_cast<const char*>(&strsize), sizeof(strsize));
          ofl.write(ID_HighspeedDecoder.c_str(), strsize+1);
    
          for( int i = 0; i < werteAnzahl; i ++ )
          {
            ofl.write(reinterpret_cast<const char*>(&Throw[i]), sizeof(int));
            ofl.write(reinterpret_cast<const char*>(&Resolution[i]), sizeof(double));
            ofl.write(reinterpret_cast<const char*>(&Coverage[i]), sizeof(double));
            ofl.write(reinterpret_cast<const char*>(&MinElementPreferred_015[i]), sizeof(double));
            ofl.write(reinterpret_cast<const char*>(&MinElementAbsolute_015[i]), sizeof(double));
            ofl.write(reinterpret_cast<const char*>(&MinElementPreferred_1545[i]), sizeof(double));
            ofl.write(reinterpret_cast<const char*>(&MinElementAbsolute_1545[i]), sizeof(double));
            ofl.write(reinterpret_cast<const char*>(&MaxBeltSpeed_StandardDecoder[i]), sizeof(double));
            ofl.write(reinterpret_cast<const char*>(&MaxBeltSpeed_HighspeedDecoder[i]), sizeof(double));
          }
    
          ofl.close();
        }
    
        bool readFromFile(AnsiString datei)
        {
          ifstream ifl(datei.c_str(), ios::in|ios::binary);
    
          int strsize;
          ifl.read(reinterpret_cast<char*>(&strsize), sizeof(strsize));
          minThrow = strsize;
    
          ifl.read(reinterpret_cast<char*>(&strsize), sizeof(strsize));
          maxThrow = strsize;
    
          ifl.read(reinterpret_cast<char*>(&strsize), sizeof(strsize));
          werteAnzahl = strsize;
    
          ifl.read(reinterpret_cast<char*>(&strsize), sizeof(strsize));
          StandardDecoder = (bool)strsize;
    
          ifl.read(reinterpret_cast<char*>(&strsize), sizeof(strsize));
          HighspeedDecoder = (bool)strsize;
    
          char *tstr;
          ifl.read(reinterpret_cast<char*>(&strsize), sizeof(strsize));
          tstr = new char[strsize+1];
          ifl.read(tstr, strsize+1);
          Linse = tstr;
          delete[] tstr;
    
          *tstr;
          ifl.read(reinterpret_cast<char*>(&strsize), sizeof(strsize));
          tstr = new char[strsize+1];
          ifl.read(tstr, strsize+1);
          ExcelDatei = tstr;
          delete[] tstr;
    
          *tstr;
          ifl.read(reinterpret_cast<char*>(&strsize), sizeof(strsize));
          tstr = new char[strsize+1];
          ifl.read(tstr, strsize+1);
          ID_StandardDecoder = tstr;
          delete[] tstr;
    
          *tstr;
          ifl.read(reinterpret_cast<char*>(&strsize), sizeof(strsize));
          tstr = new char[strsize+1];
          ifl.read(tstr, strsize+1);
          ID_HighspeedDecoder = tstr;
          delete[] tstr;
    
          for( int i = 0; i < werteAnzahl; i ++ )
          {
            int si;
            ifl.read(reinterpret_cast<char*>(&si), sizeof(si));
            Throw.push_back(si);
    
            double siz;
            ifl.read(reinterpret_cast<char*>(&siz), sizeof(siz));
            Resolution.push_back(siz);
    
            ifl.read(reinterpret_cast<char*>(&siz), sizeof(siz));
            Coverage.push_back(siz);
    
            ifl.read(reinterpret_cast<char*>(&siz), sizeof(siz));
            MinElementPreferred_015.push_back(siz);
    
            ifl.read(reinterpret_cast<char*>(&siz), sizeof(siz));
            MinElementAbsolute_015.push_back(siz);
    
            ifl.read(reinterpret_cast<char*>(&siz), sizeof(siz));
            MinElementPreferred_1545.push_back(siz);
    
            ifl.read(reinterpret_cast<char*>(&siz), sizeof(siz));
            MinElementAbsolute_1545.push_back(siz);
    
            ifl.read(reinterpret_cast<char*>(&siz), sizeof(siz));
            MaxBeltSpeed_StandardDecoder.push_back(siz);
    
            ifl.read(reinterpret_cast<char*>(&siz), sizeof(siz));
            MaxBeltSpeed_HighspeedDecoder.push_back(siz);
          }
    
          ifl.close();
        }
    };
    

    und so lad/speicher ichs:

    Kamera test;
      Kameras[0].saveToFile(getProgDir(),"pln");
      test.readFromFile(getProgDir() + "a.pln");
      AnsiString dummy = (AnsiString)test.minThrow;
      Application->MessageBox(dummy.c_str(),"Dummy",MB_ICONINFORMATION);
    


  • Welches Problem hattest du den damals?

    Der Code hat ein bischen viel reinterpret_casts abbekommen
    findest du nicht?



  • Welches Problem hattest du den damals?

    Das überhaupt hinzubekommen.

    Der Code hat ein bischen viel reinterpret_casts abbekommen
    findest du nicht?

    Wass sollte ich dann verwenden?



  • Dragonfire schrieb:

    Welches Problem hattest du den damals?

    Das überhaupt hinzubekommen.

    Und was meinst, wieviele Leute jetzt losgehen, um das Board nach deinem letzten Thread zu dem Thema zu durchsuchen?

    Der Code hat ein bischen viel reinterpret_casts abbekommen
    findest du nicht?

    Wass sollte ich dann verwenden?

    Gegenfrage: Was genau hast du eigentlich vor?

    @Storm: Beim binären Speichern über fstreams kommst du an reinterpret_cast<> nicht vorbei (außer mit einem C-Cast, aber der ist noch schlimmer).



  • Hi,

    erstmal würde ich das anders strukturieren:

    Entweder

    A) gehören

    Throw
    Resolution
    Coverage
    MinElementPreferred_015
    MinElementAbsolute_015
    MinElementPreferred_1545
    MinElementAbsolute_1545
    MaxBeltSpeed_StandardDecoder
    MaxBeltSpeed_HighspeedDecoder
    

    jeweils zusammen, dann solltest Du sie auch entsprechend bündeln.
    Beispiel:

    struct Wert {
       int Throw;
       double Resolution, Coverage, MinElementPreferred_015, MinElementAbsolute_015,
              MinElementPreferred_1545, MinElementAbsolute_1545, 
              MaxBeltSpeed_StandardDecoder, MaxBeltSpeed_HighspeedDecoder
       bool saveToFile(AnsiString pfad, AnsiString endung);
       bool loadFromFile(AnsiString pfad, AnsiString endung);
    };
    
    bool Wert::saveToFile(AnsiString pfad, AnsiString endung) {
       // Hier die Implementierung rein
    }
    
    bool Wert::loadFromFile(AnsiString pfad, AnsiString endung) {
       // Hier die Implementierung rein
    }
    
    struct Kamera
    {
        int         minThrow;
        int         maxThrow;
        bool        StandardDecoder;
        bool        HighspeedDecoder;
        AnsiString  Linse;
        AnsiString  ExcelDatei;
        AnsiString  ID_StandardDecoder;
        AnsiString  ID_HighspeedDecoder; 
        vector<Wert> Werte;
        // separaten "Werte-Zähler" braucht's nicht: Das steht in Werte.size()
        bool saveToFile(AnsiString pfad, AnsiString endung) {
          for(vector<Wert>::const_iterator it = Werte.begin();  it != Werte.end(); ++it)
             if(!it->saveToFile(pfad, endung)) return false;
          return true;
       }
       bool loadFromFile(AnsiString pfad, AnsiString endung) {   // ebenso }
    ....
    };
    

    Oder

    😎 sie sind unabhängig von einander, dann solltest Du die Vektoren auch getrennt abspeichern.
    Das ist letztlich noch einfacher, weil Du eigentlich nur 2*2 Funktionen (bzw. 2*1 template) brauchst:

    template <typename T>
    bool saveVectortoFile(vector<T> const&, AnsiString pfad, AnsiString endung);
    
    template <typename T>
    bool loadVectorFromFile(vector<T>&, AnsiString pfad, AnsiString endung);
    

    Zwischen A) und 😎 musst Du fachlich entscheiden. Dein Ansatz birgt das Risiko, dass Dir "Dinge auseinanderlaufen".

    Noch ein paar Tipps:

    • Vergiss das "Binär speichern mittels reinterpret_cast !!
      Hat nur Nachteile (Compiler-/Plattformabhängig, unleserlich, nicht manuell zu korrigieren/prüfen, ...) und kaum nennenswerte Vorteile (bei kleinen Werten braucht ein "int" sogar mehr Platz als seine Stringrepräsentation)....
    • Überlege Dir, ob statt des exotischen "saveTo/loadFromFile()" nicht eine Streamstruktur besser geeignet wäre, wo Du in einen ostream schreibst/istream liest.
      Vorteil1: Funktioniert mit allen "Datenpools" - egal ob in File, Konsole, Netzwerk, Drucker, ....
      Vorteil2: Hält "File-Zeug", mit dem die Fachobjekte wie "Kamera" eigentlich nichts zu tun haben, von ihnen fern => sauberere Aufgabentrennung. Beispiel:
    int main() {
       Kamera k;
    
       ofstream kameraFile("KF.txt");
       iNetzWerk_stream netz(myNet_Option);
    
       netz >> k; // Kameradaten vom Netz einlesen ...
       k.doSomething();
       kameraFile << k; // .. in File speichern ...
       cout << k;   // .. und zur Kontrolle auf Konsole ausgeben.
    ...
    

    => Die Verwaltung/Konfiguration der verschiedenen "Pools" (Netz, File, Konsole, ...) braucht die Kamera nicht mehr zu interessieren, sondern wird dort definiert, wo es Hauptaufgabe ist (hier in main(), kann aber auch separate "KonfigKlasse" sein).

    • Beschäftige Dich mal mit exceptions; könnte sein, dass das bei Dir besser "klappt" als das Arbeiten mit Returnwerten.

    Gruß,

    Simon2.


Anmelden zum Antworten