Array speichern



  • 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



  • int len;
    int Size;
    fstream File2("List.dat", ios::in|ios::binary);
    if (File2.is_open())
    {
        File2.read((char*)&Size, sizeof(Size));
        cout << "The Size of the Array is: "<<Size<<endl;
    }
        String* Searchword = new String[Size+1];
    
        if (File2.is_open())
            {
        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();
        }
     File2.close();
        cout << Searchword[0].c_str();
    

    so gehts!! gibts da noch ne elegantere lösung???
    kann ich des irgendwie als global deklarieren??



  • Hallo

    - "geht nicht" ist keine ausreichende Fehlerbeschreibung
    - Rücke deinen Code vernünftig ein, um den lesbarer zu machen
    - jedes Symbol muß in dem aktuellen Scope deklariert sein, um ihn zu benutzen. Deshalb ist klar, warum hier der Kompiler den Ausdruck nicht kennt

    if (...)
    {
      String* Searchword = new String[Size+1];
      ...
      cout << Searchword[0].c_str(); // im richtigen Scope
      ...
      if (...)
      {
        cout << Searchword[0].c_str(); // immer noch im richtigen Scope  
      }
    }
    cout << Searchword[0].c_str(); // nicht mehr im richtigen Scope, Kompiler kennt das nicht mehr
    

    das sind aber alles Grundkenntnisse von C++, die du kennen solltest.
    Wenn nicht, dann arbeite ein passendes Tutorial durch.

    /Edit :

    kann ich des irgendwie als global deklarieren??

    Bitte nicht. Globale Variablen sollten nur wenn wirklich nötig verwendet werden.
    Benutze Funktionsparameter und (statische) Klassenmember stattdessen.

    bis bald
    akari



  • akari schrieb:

    Benutze Funktionsparameter und (statische) Klassenmember stattdessen.

    Was genau meinst du damit??
    Das es in den richtigen Klammern sein muss habe ich inzwischen ja herausgefunden



  • Hallo

    Was genau meinst du damit??

    In einem konkreten Beispiel läßt sich das nicht umesetzen und ist auch nicht nötig. Es reicht wenn du innerhalb der Funktion die entsprechenden Variablen an der richtigen Stelle deklarierst,
    Die von mir genannten Prinzipien brauchst du erst, wenn du Variablen bzw. deren Werte zwischen mehreren Funktionen austauschen willst.

    bis bald
    akari



  • na jetzt hab ich ja die daten aus der datei herausgelesen und will nun ja auch noch was damit machen sonst hätte das ganze ja keinen zweck gehabt und deshalb wollte ich auch gerne wissen wie ich die variable für andere Funktionen bzw außerhalb der Funktion nutzen könnte...


Anmelden zum Antworten