Structure-array speichern



  • Hallo,

    Warum nimmst du nicht, wie schon vorgeschlagen die TStream-Variante. Die Datei sollte sowieso außerhalb der read/write-Funktionen geöffnet (und dann auch geschlossen) werden. Wenn du unbedingt die FileOpen etc. Varianten verwenden willst, kannst du ja auch das Filehandle übergeben. So wie du es jetzt hast ist es wirklich recht unflexibel und zudem auch langsam. Das ständige Öffnen und Schließen der Dateien ist nicht so richtig gut.



  • Hallo Sunday, hallo Braunstein,

    vielen Dank für eure Hinweise.
    Ich hab zunächst einmal versucht, einige Tips in meine jetzige Lösung einzuarbeiten:

    struct Ding
            {
            AnsiString Name;
            int a;
            float DM;
            int openWrite (AnsiString DatName, bool neu);
            int openRead (AnsiString DatName);
            void closeDatei( int Handle);
            void write(int oFileHandle);
            void read( int iFileHandle);
    
            }     ;
    

    Es funktioniert auch gut. Allerdings sieht die Verwendung von openWrite,bzw openRead oder closeDatei recht unsauber aus:
    z.B

    int Handle = test[0].openWrite("daten.txt",true);
    

    Es sieht aus, als würde speziell für das Arrayelement test[0] ein Handle geholt. Das Handle gilt allerdings für alle dann folgenden Schreibaktionen.

    int Handle = test[0].openWrite("daten.txt",true);
    for (int i = 0; i<5; i++)
        {
        test[i].write(Handle) ;
        }
    test[0].closeDatei(Handle);
    

    Funktioniert zwar, aber find ich nicht so schön.

    Sunday schrieb:

    aber vielleicht überdenkst du eher noch mal dein klassendesign und speicherst die daten direkt in der klasse.

    Mir scheint tatsächlich jetzt auch, dass im Ansatz bereits die Probleme entstehen.
    Ich werde das Ganze jetzt einmal so angehen:

    1. struct ding {alle Eigenschaften vom Ding};
    2. class DingeVerwaltung {Array mit Ding und alles zum Speichern und Laden}

    ich glaube, dann ist die Lösung sehr viel schöner.

    grüße von sehreilig

    Schon Fertig:

    //--------------------------------------------------------------------------
    struct Ding
          {
            AnsiString Name;
            int a;
            float DM;
             }     ;
    
    class DingeVerwalten
            {
            public:
            Ding Dinge[5];
            AnsiString DatName;
    
            void write();
            void read();
    
            }     ;
    //-----------------------------------------------------------------------------
    
    void DingeVerwalten::write()
    {
    
     int Handle;
     Handle = FileCreate(DatName);
    
     for (int i =0; i<5; i++)
         {
    
         int strsize = Dinge[i].Name.Length();
    
         FileWrite(Handle,(void *) &strsize, sizeof(strsize)) ;
         FileWrite(Handle, Dinge[i].Name.c_str(), strsize +1);
         FileWrite(Handle, (void *) &Dinge[i].a, sizeof(Dinge[i].a));
         FileWrite (Handle, (void *) &Dinge[i].DM, sizeof(Dinge[i].DM));
         }
         FileClose(Handle);
    
    } ;
    
    //-----------------------------------------------------------------------------
    
    void DingeVerwalten::read()
    {
     int Handle = FileOpen(DatName,fmOpenRead );
     int strsize;
     for (int i = 0; i<5; i++)
         {
         FileRead(Handle,(void *) &strsize, sizeof(strsize));
         char *tstr= new char[strsize + 1];
         FileRead(Handle,tstr, strsize+1);
         Dinge[i].Name = AnsiString(tstr);
         FileRead(Handle,(void *) &Dinge[i].a, sizeof(Dinge[i].a));
         FileRead (Handle, (void *) &Dinge[i].DM, sizeof(Dinge[i].DM));
         }
      FileClose(Handle);
    } ;
    

    erstmal ohne Fehler abfangen.

    Über Komentare und weitere Hinweise freue ich mich.



  • Der Ansatz ist schonmal in Ordnung. Nur solltest du das eigentliche Schreiben wieder zurück nach Ding verlegen (sprich: genau das, was in der for-Schleife liegt).

    Dann erzeugst du das Handle, durchläufst die for-Schleife und gibst bei einem Dinge.write Aufruf das Handle mit.

    Das wäre dann die Lösung die auch schon einige Seiten weiter vorne vorgeschlagen wurde.



  • Hallo Dasd,
    danke für deinen Hinweis.
    Jetzt sieht das ganze so aus und funktioniert wirklich gut:

    struct Ding
          {
            AnsiString Name;
            int a;
            float DM;
            void write( int Handle);
            void read (int Handle);
             }     ;
    
    class DingeVerwalten
            {
            public:
            Ding Dinge[5];
            AnsiString DatName;
    
            void write();
            void read();
    
            }     ;
    

    Du und Braunstein bevorzugen wohl allerdings eine TStream-Variante.
    Bei meinen Ausflügen durch die Borland-Hilfe fand ich zu meiner jetzigen Lösung viele Hinweise, so kam es zu dieser Lösung. An der Klassenstruktur wird sich vermutlich mit TStreams nicht viel ändern.

    Wieso sind TStreams besser geeignet? Was meint Sunday damit:

    Schreib/Lese-Funktionen sind sehr unflexibel.

    Über eine Antwort würde ich mich freuen.

    Nochmals allen vielen Dank. Grüße von sehr eilig

    Inzwischen hab ich auch eine Variante mit TStreams erprobt.
    Ich muss sagen: Ich bin jetzt sehr zufrieden, meine anfängliche Problem sind durch die Unterstützung hier im Forum voll gelöst ! Zusätzlich hab ich einiges durch eure Tips dazugelernt, was mir alleine aus dem Erarbeiten aus Büchern oder aus der Hilfe kaum möglich gewesen wäre. SUPER 🙂


Anmelden zum Antworten