Array speichern



  • Hi hab des jetzt aus dem Beispiel kopiert und es scheint auch zu funktionieren...
    Hiermal mein Quelltext:

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    #include <iostream>
    #include <fstream>
    #include "Programm1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
    
    enum Spaltenname{Adresse,Interval,Zeichen};
    using namespace std;
    // Einen Person-Datensatz definieren
    
    // fstream damit die Datei zuerst schreibend und dann lesend geöffnet werden kann.
    fstream File("Person.dat", ios::out|ios::binary);
    if (File.is_open())
    {
        // Nur zwei Datensätze schreiben.
        // Hier wäre eine Fehlerprüfung angebracht
    char* a[2][3] = {{"http://www.adresse1.html","10","160"},{"http://www.adresse2.de/","15","140"}};
    Label2->Caption = a[1][Adresse];
            // Aktuelle Person in der Datei speichern.
            File.write((const char*)&a, sizeof(a));
    
        File.close();   // Datei schließen
    }
    // Datei zum Lesen öffnen.
    File.open("Person.dat", ios::in|ios::binary);
    if (File.is_open())
    {
       //enum Spaltenname{Adresse,Interval,Zeichen};
    char* b[2][3];
        while (File.read((char*)&b, sizeof(b)))
        Label1->Caption = b[0][Adresse];
        }
    
    }
    //---------------------------------------------------------------------------
    

    jetzt hab ich noch ein Kleines Programm geschrieben mit welchem ich ausschließlich aus der Datei lesen will. leider ändert sich des caption nicht:

    hiermal der Quelltext von dem zweiten Programm:

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    #include <iostream>
    #include <fstream>
    #include "Programm2.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
    enum Spaltenname{Adresse,Interval,Zeichen};
    using namespace std;
    // Einen Person-Datensatz definieren
    
    // fstream damit die Datei zuerst schreibend und dann lesend geöffnet werden kann.
    fstream File("Person.dat", ios::out|ios::binary);
    
    // Datei zum Lesen öffnen.
    File.open("Person.dat", ios::in|ios::binary);
    if (File.is_open())
    {
    char* b[2][3];
        while (File.read((char*)&b, sizeof(b)))
        Label1->Caption = b[0][Adresse];
        }
    
    }
    //---------------------------------------------------------------------------
    

    Ich kann einfach keinen Fehler finden!! Und eine Fehlermeldung bekomme ich auch nicht!!Komischerweise scheint es ja im ersten programm zu funktionnieren.

    Kann mir jemand helfen??

    MfG Straightflush



  • kann mir keine sagen wo mein (vermutlich Denk-) Fehler liegt??



  • Hallo

    du hast bereits hier

    Croatiancow schrieb:

    Artikel alle[2]={NULL};

    Straightflush schrieb:

    char* a[2][3]

    einenj entscheidenden Unterschied.
    Das Original arbeitet mit einem Array von Heapobjekten, deren sizeof() auch die tatsächliche Größe ergibt.
    Du aber arbeitest mit einem Array von Pointern auf String-Literalen. Da wird bei sizeof nur der Platz für die Pointer berechnet.
    Deshalb dürfte schon allein die erstellte Datei Person.dat nicht richtig ist.

    bis bald
    akari



  • Ich hab nun mal alles nochmal verändert und arbeite nun mit einem struct

    Hier ist der Quelltext von dem Programm welches die Datei schreibt und gleich ausließt... funktioniert super.

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    #include <iostream>
    #include <fstream>
    #include "Programm1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    using namespace std;
    TForm1 *Form1;
    struct Eintrag
    {
    char adresse[40];
    int zeichen;
    int interval;
    };
    
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
    Eintrag first;
    first.zeichen = 126;
    first.interval = 15;
    strcpy(first.adresse,"www.google.de");
    
    // fstream damit die Datei zuerst schreibend und dann lesend geöffnet werden kann.
    fstream File("Person.dat", ios::out|ios::binary);
    if (File.is_open())
    {
        // Nur zwei Datensätze schreiben.
        // Hier wäre eine Fehlerprüfung angebracht
    
    Label2->Caption = first.adresse;
            // Aktuelle Person in der Datei speichern.
            File.write((const char*)&first, sizeof(first));
    
        File.close();   // Datei schließen
    }
    // Datei zum Lesen öffnen.
    File.open("Person.dat", ios::in|ios::binary);
    if (File.is_open())
    {
    
    Eintrag second;
        while (File.read((char*)&second, sizeof(second)))
        Label1->Caption = second.adresse;
        }
    
    }
    //---------------------------------------------------------------------------
    

    Und hier ist das Programm welches nur lesen soll: in dem Fall erhalte ich als ausgabe 1310016.

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    #include <iostream>
    #include <fstream>
    #include "Programm2.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    using namespace std;
    TForm1 *Form1;
    struct Eintrag
    {
    char adresse[40];
    int zeichen;
    int interval;
    };
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
    // fstream damit die Datei zuerst schreibend und dann lesend geöffnet werden kann.
    fstream File("Person.dat", ios::out|ios::binary);
    
    // Datei zum Lesen öffnen.
    File.open("Person.dat", ios::in|ios::binary);
    if (File.is_open())
    {
    
    Eintrag second;
        File.read((char*)&second, sizeof(second));
        Label1->Caption = second.zeichen;
        }
    
    }
    //---------------------------------------------------------------------------
    

    Verändere ich das lesen zu einer while Schleife erhalte ich wieder kein anderes Caption (sprich das Caption "Label1" bleibt).

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    #include <iostream>
    #include <fstream>
    #include "Programm2.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    using namespace std;
    TForm1 *Form1;
    struct Eintrag
    {
    char adresse[40];
    int zeichen;
    int interval;
    };
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
    // fstream damit die Datei zuerst schreibend und dann lesend geöffnet werden kann.
    fstream File("Person.dat", ios::out|ios::binary);
    
    // Datei zum Lesen öffnen.
    File.open("Person.dat", ios::in|ios::binary);
    if (File.is_open())
    {
    
    Eintrag second;
        while(File.read((char*)&second, sizeof(second)))   //<--- Veränderung!!!!
        Label1->Caption = second.zeichen;
        }
    
    }
    //---------------------------------------------------------------------------
    

    Ich hab keine Ahnung was ich jetzt noch machen soll...
    Muss es etwas ein array aus struct Objekten sein?!

    Ich wäre wirklich sehr dankbar wenn mir jemand nen guten Tipp gibt.

    MfG Straightflush



  • Kann mir echt keiner helfen?? Ich bekomme nicht raus wo der Fehler liegt!!



  • Geh doch mal mit dem Debugger durch und schau nach was wirklich eingelesen wird.
    Wozu soll diese while-Schleife eigentlich gut sein? Die würde doch bei dir so lange durchlaufen, bis du einen Lesefehler hast, und dann steht in deiner Caption nur noch Müll drin.



  • und wie geht des bei Borland

    Habe bemerkt das wenn ich die Datei mim zweiten programm lesen will die Datei 0byte groß wird...

    Wie kann das sein??



  • Da ist wohl nichts rausgeschrieben worden.
    Hier nochmal der Hinweis auf den Debugger.



  • Hab das problem mit der 0byte datei behoben weiß leider nicht genau wie
    ich hab das ganze jetzt in einem Programm geschrieben was einfacher zum lesen ist...
    Ich bekomme in diesem Fall jedoch nur wirre Zeichen als Ausgabe in Label2...

    Hier mal der Code von dem neuen Programm:

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    #include <iostream>
    #include <fstream>
    #include "Programm1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    using namespace std;
    TForm1 *Form1;
    struct Eintrag
    {
    char adresse[40];
    int zeichen;
    int interval;
    };
    
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
    Eintrag first;
    first.zeichen = 1111;
    first.interval = 15;
    strcpy(first.adresse,"www.google.de");
    
    // fstream damit die Datei zuerst schreibend und dann lesend geöffnet werden kann.
    fstream File("Testdatei", ios::out|ios::binary);
    if (File.is_open())
    {
    
    Label1->Caption = first.adresse;
    
        File.write((const char*)&first, sizeof(first));
    
        File.close();   // Datei schließen
    }
    
    fstream File2("Testdatei", ios::in|ios::binary);
    
    // Datei zum Lesen öffnen.
    File2.open("Testdatei", ios::in|ios::binary);
    if (File2.is_open())
    {
    
    Eintrag second;
        File2.read((char*)&second, sizeof(second));
        Label2->Caption = second.adresse;
        }
     File2.close();
    
    }
    //---------------------------------------------------------------------------
    


  • Lass bitte mal das hier weg

    File2.open("Testdatei", ios::in|ios::binary);
    

    Du hast die Datei ja schon im Konstruktor geöffnet. Dann verlege den Code mal aus OnCreate raus. Entweder in einen Click-Event oder auch in OnShow.



  • Danke jetzt klappts!!! Kann sogar im OnCreat bleiben!!!!!



  • Versuche, wenns irgend geht OnCreate und OnDestroy nicht zu nutzen, sondern statt dessen besser Destruktor und Konstruktor. Es gab da irgendwo mal einen Artikel wo beschrieben wurde warum das so ist.
    Hier ist der ja
    http://support.borland.com/thread.jspa?messageID=11735



  • Hi ich habe noch eine Frage...
    Wenn ich in meine Datei ein Array aus Struct Elementen schreibe,
    beim rauslesen aber vorher nicht weiß wie groß das array ist wie kann ich dann vorher herausfinden wie groß das array sein muss in das geschrieben wird?

    Meine Ideen waren:
    - Vorher ein Int-Wert abspeichern der angibt wieviele Elemente das Array hat und aus dieser Angabe das neue Array zu erzeugen.

    - Erst alles in ein übergroßes Array zu laden in dem aufjedenfall alle reinpassen dann die Elemente zählen (oder beim auslesen mitzählen) ein zweites array erzeugen,
    die Elemente kopieren, dann das Buffer-Array löschen

    Was haltet ihr von dieser Idee???
    array[] funktioniert leider nicht 😞

    MfG Straightflush



  • Hallo

    Meine Ideen waren:
    - Vorher ein Int-Wert abspeichern der angibt wieviele Elemente das Array hat und aus dieser Angabe das neue Array zu erzeugen.

    Ist okay

    - Erst alles in ein übergroßes Array zu laden in dem aufjedenfall alle reinpassen dann die Elemente zählen (oder beim auslesen mitzählen) ein zweites array erzeugen,
    die Elemente kopieren, dann das Buffer-Array löschen

    Ist schlecht, weil du dann wieder eine (zwar große) Maximalgröße und dazu noch Kopieroverhead hast

    Die eigentliche Lösung ist die Verwendung eines dynamischen Arrays. Das VCL-Mittel dafür ist DynamicArray (siehe Suche hier im BCB-Forum), ich empfehle dir aber das wesentlich elegantere und umfangreichere Mittel aus dem C++ Standard : std::vector (siehe Suche im C++ Forum, sowie den Magazin-Artikel über die STL-Container).

    Bei beitem hast du am Anfang ein leeres Array. Mit einer while-Schleife liest du solange ein, bis du am Ende der Datei bist. Bei jedem Durchgang liest du die Werte für ein Element ein und hängst es an das Array.

    bis bald
    akari



  • Habs jetzt mit der ersten Methode versucht...
    leider wird nur der Intergerwert ausgelesen...

    Ich vermutet stark das es etwas damit zu tun hat das ich String-Wert abspeichern will... kann es sein das sich nur char binär abspeichern lassen===

    hier mal der Quelltext von dem Programm das in die Datei schreibt:

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #include <fstream>
    #include <iostream>
    #pragma hdrstop
    using namespace std;
    
    #pragma argsused
    int main(int argc, char* argv[])
    {
    String Searchword[]={"hallo","hallo1","hallo2","hallo3"};
    
    fstream File("List.dat", ios::out|ios::binary);
    if (File.is_open())
    {
        int Size = sizeof(Searchword)/sizeof(Searchword[0]);
    
        File.write((const char*)&Size, sizeof(Size));
    
        for(int i=0; i < sizeof(Searchword)/sizeof(Searchword[0]); i++)
        {
        String Buffer = Searchword[i];
        File.write((const char*)&Buffer, sizeof(Buffer));
        }
    
        File.close();   // Datei schließen
    }
    
    system("PAUSE");
    return 0;
    }
    

    Hier von dem Programm das rauslesen soll...

    //---------------------------------------------------------------------------
    
    #include <vcl.h>2
    #include <fstream>
    #include <iostream>
    #pragma hdrstop
    using namespace std;
    
    #pragma argsused
    int main(int argc, char* argv[])
    {
    
    fstream File2("List.dat", ios::in|ios::binary);
    if (File2.is_open())
    {
    
    int Size;
        File2.read((char*)&Size, sizeof(Size));
        cout << "Array-Size = "<<Size<<endl;
        //String *Searchword = new String[Size];
        for(int i=0;i < Size; i++)
        {
        String Buffer;
        File2.read((char*)&Buffer, sizeof(Buffer));
        cout << Buffer.c_str() << "#" << endl;
        }
    
        }
     File2.close();
    system("PAUSE");
    
    return 0;
    }
    //---------------------------------------------------------------------------
    

    oder liegt mein Fehler woanders???

    wenn es an den strings liegt ist es dann möglich so etwas

    char test[40];
    

    in ein array zu packen?? ist ja schon ein array an sich...
    oder muss ich dann eine zweite dimension dazu nehmen??

    Schonmal vielen Dank für die Antworten!!
    MfG Straightflush



  • Hallo,

    Du hast da oben ein Array von AnsiStrings. Wenn du die binär rausschreiben willst, mußt du nicht nur die Größe des Array, sondern auch die Länge jedes Einzelstrings mit ausgeben.

    File.write((const char*)&Buffer, sizeof(Buffer));
    

    Das hier geht schon gar nicht. Du castest ein AnsiString in ein const char*. Ich weiß jetzt nicht was dabei rauskommt, aber mit Sicherheit nicht das was du erwartest. sizeof(Buffer) gibt dir auch nicht die Länge des Strings, sondern nur die Größe einer AnsiStringinstanz.
    Einen AnsiString kann man so rausschreiben.

    int len = Buffer.Length();
    File.write((const char*)&len, sizeof(len));
    File.write(Buffer.c_str(), len);
    

    und so mußt du es auch einlesen. Erst die Länge, dann die Anzahl der Bytes in einen char* Puffer un zu Schluß das in den AnsiString.
    Bsp.

    int len;
    File2.read((char*)&len, sizeof(len));
    char* buffer = new char[len+1];
    File2.read((buffer,len);
    buffer[len] = '\0';
    String str = buffer;
    delete[] buffer;
    

    Du kannst auch alles im Textmodus rausschreiben. Dann wird zwar die Datei etwas größer und von jedem lesbar. Allerdings vereinfacht sich das Lesen und schreiben stark.



  • Habs so versucht...
    Bekomme leider immer die Meldung "Speicheradresse muss verwendet werden"...

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    #include <fstream>
    using namespace std;
    #include <iostream>
    //---------------------------------------------------------------------------
    
    #pragma argsused
    int main(int argc, char* argv[])
    {
    String Searchword[]={"hallo","hallo1","hallo2","hallo3"};
    fstream File("List.dat", ios::out|ios::binary);
    if (File.is_open())       // Wenn Datei geöffnet ist
    {
        int Size = sizeof(Searchword)/sizeof(Searchword[0]); // Anzahl der Suchwörter berechnen
        File.write((const char*)&Size, sizeof(Size));        // und in Datei abspeichern
    
        for(int i=0; i < sizeof(Searchword)/sizeof(Searchword[0]); i++)//Anzahl der Durchläufe entspricht Anzahl der Suchwörter
        {
        cout << Searchword[i].c_str() << " hat die laenge: " << Searchword[i].Length() << endl;
        int len = Searchword[i].Length();
        File.write((const char*)&len, sizeof(len));  // Größe des Wortes in Datei speichern
        File.write(&Searchword[i].c_str(), len);     // Wort in char und dann in Datei speichern   <-------- HIER IST DIE FEHLERZEILE 
        cout << Searchword[i].c_str() << " wurde mit der Laenge: " << len << " in die Datei gespeichert" << endl;
        }
    
        File.close();   // Datei schließen
    }
    
    system("PAUSE");  return 0;
            }
    //---------------------------------------------------------------------------
    

    Kann mir jemand helfen???



  • Hallo

    AnsiString::c_str() liefert dir doch schon einen Pointer, da brauchst du nicht extra die Adresse zu holen

    File.write(Searchword[i].c_str(), len);
    

    bis bald
    akari



  • Lass einfach das & vor Searchword weg. c_str() gibt dir ja schon ein const char*.
    [edit]Heute bin ich wohl immer zu spät. 😞 [edit]



  • Super Danke jetzt funktionierts!!!!!

    Hab noch ne Frage zu dem '/0'...
    Wieso muss das an das Ende des Strings angefügt werden bzw warum wird das nicht mit abgespeichert???

    und hier habe ich noch eine Frage:

    if (File2.is_open())
    {
    
    int len;
    int Size;
        File2.read((char*)&Size, sizeof(Size));
        cout << "The Size of the Array is: "<<Size<<endl;
        String* Searchword = new String[Size+1];
        for(int i=0;i < Size; i++)
        {
        File2.read((char*)&len, sizeof(len));
        char* buffer = new char[len+1];
        File2.read(buffer,len);
        buffer[len] = '\0';
        Searchword[i] = buffer;
        delete[] buffer;
        cout << Searchword[i].c_str() << endl;
        }
        cout << Searchword[0].c_str();           <----- WARUM GEHT DAS
        }
     File2.close();
        cout << Searchword[0].c_str();<------ DAS ABER NICHT?!
    

    MfG Straightflush


Anmelden zum Antworten