fwrite und fread für ein Array



  • Hallo zusammen, kann mir bitte jemand auf die Finger schauen!? Ich versuche schon sein einiger Zeit die Funktionen zum Speichern und Laden von meinem Datentyp zu realisieren was nicht so recht zu klappen scheint.

    void __fastcall TfrmLoadAndSave::btnSaveDatClick(TObject *Sender)
    {
            FILE *f;
            AnsiString asFilename;
            TData myData[10];
    
            for(int i=0; i<10; i++)
            {
                    myData[i].myInt = i;
    
            }
    
            if (SaveDialog1->Execute())
            {
                    asFilename = SaveDialog1->FileName;
                    f = fopen(asFilename.c_str(),"wb");
                    for(int i=0; i<sizeof(myData); i++)
                    {
                            fwrite(&myData[i], sizeof(TData), 1, f);
                    }
                   fclose(f);
            }
    
    }
    //---------------------------------------------------------------------------
    void __fastcall TfrmLoadAndSave::btnLoadDatClick(TObject *Sender)
    {
            FILE *f;
            AnsiString asFilename;
            TData myData[10];
    
            if (OpenDialog1->Execute())
            {
                    asFilename = OpenDialog1->FileName;
                    f = fopen(asFilename.c_str(),"wb");
                    for(int i=0; i<sizeof(myData); i++)
                    {
                            fread(&myData[i], sizeof(TData), 1, f);
                    }
                    fclose(f);
            }
    
    }
    

    Mir geht es speziell darum, wie ich ein ganzes Array voller Werte in der Datei ablegen kann und später die Datei wieder in ein Array einlesen kann.

    MfG
    coder24h



  • Hallo

    wenn du den Builder schoin benutzt, dann nimm doch gleich TStringList. Wie das steht in der FAQ des Builder-Subforums unter den TOP 3.

    bis bald
    akari



  • Es ist mir schon klar, dass diese Funktionen nicht mehr die neuesten sind, dafür werden die von jedem c bzw. c++ Compiler unterstützt. Hat jemand einen Vorschlag was ich falsch gemacht haben könnte?
    *
    Mit freundlichen Grüßen
    coder34h
    *



  • coder24h schrieb:

    Es ist mir schon klar, dass diese Funktionen nicht mehr die neuesten sind, dafür werden die von jedem c bzw. c++ Compiler unterstützt.

    das ist nciht von dem Compiler abhängig, sondern von der VCL.
    und da du die VCL sowieso schon brauchst ("AnsiString" "TSaveDialog"), kannst du doch auch gleich die vorzüge davon geniessen. -> siehe akaris posting



  • Hallo

    es spielt doch keine Rolle ob ein kleiner Teil deines Codes von jedem C und C++ Compiler verstanden wird, wenn du das ganze in eine Compiler-abhängige Klassenbibliothek (die VCL des Builders) einbettest und damit das ganze Programm eh nur mit dem Builder übersetzt werden kann.
    Wenn du aber standard-konforme Programme schreiben willst, dann erstelle im Builder ein Konsolenprojekt und verwende std::fstream. Dazu findest du im C++FAQ einen Thread namens Dateien und Ströme.

    bis bald
    akari



  • Ein Fehler ist in der For-Schleife:

    for(int i=0; i<sizeof(myData); i++)
    

    sizeof(myData) liefert nicht die Anzahl der Feldelemente sondern die Größe des vom Feld belegten Speicherplatzes, also sizeof(TData)*Feldgröße. Du willst sicherlich über sizeof(myData)/sizeof(TData) iterieren.

    Ein weiterer möglicher Fehler ist, daß der Typ TData Zeiger enthält. Falls dem so ist, werden die Zeiger gespeichert aber nicht die Daten.

    Falls dein Feld nicht immer gleich lang sein sollte, muß beim Laden abgefragt werden, ob die Datei lang genug ist, sonst wird irgendwann ein Fehler durch Lesen hinterm Dateiende ausgelöst werden.



  • Ich würde, wie von akari schon gesagt hier lieber mit Streams arbeiten. Die kennt auch jeder C++-Compiler. Desweiteren wäre es gut, die Anzahl der Array-Element mit abzuspeichern (als Erstes). Das macht alles etwas flexibler und weniger fehleranfällig.
    Noch besser wäre es, der struct passende read/write-Funktionen für Streams zu geben. Mehr könnte man erst sagen, wenn man die Deklaration von TData kennt.



  • Ich Danke für Ihre Hilfsbereitschaft!
    TData ist ein struct der keine Zeiger in sich trägt. Dank Morris Szyslak habe ich noch mal die Funktionen verändert und man sieht schon mal, dass etwas in die Datei geschrieben wird! Beim auslesen bekomme ich aber nicht die richtigen Werte raus.

    struct TData
    {
       int myInt;
    };
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
            FILE *f;
            AnsiString asFilename;
            TData myData[10];
    
            for(int i=0; i<10; i++)
            {
                    myData[i].myInt = i;
    
            }
    
            if (SaveDialog1->Execute())
            {
                    asFilename = SaveDialog1->FileName;
                    f = fopen(asFilename.c_str(),"wb");
                    for(int i=0; i<sizeof(myData)/sizeof(TData); i++)
                    {
                            fwrite(&myData[i], sizeof(TData), 1, f);
                    }
                   fclose(f);
            }
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
            FILE *f;
            AnsiString asFilename;
            TData myData[10];
    
            if (OpenDialog1->Execute())
            {
                    asFilename = OpenDialog1->FileName;
                    f = fopen(asFilename.c_str(),"wb");
                    for(int i=0; i<sizeof(myData)/sizeof(TData); i++)
                    {
                            fread(&myData[i], sizeof(TData), 1, f);
                    }
                    fclose(f);
            }
    
            for(int i=0; i<10; i++)
            {
                    ShowMessage(IntToStr(myData[i].myInt));
    
            }
    
    }
    


  • Müßte das Öffnen zum Lesen nicht so heißen

    f = fopen(asFilename.c_str(),"rb");
    


  • Danke Braunstein, das hat mein Problem jetzt eliminiert!

    Ich habe einen schönen Link hier gefunden, der zu dem Thema gut passen würde:

    http://www.c-plusplus.net/forum/viewtopic-var-t-is-39351.html

    Noch mal vielen Dank!
    coder24h


Anmelden zum Antworten