Inhalt eines Arrays in datei speichern und wieder auslesen?



  • Hallo

    mit dem TOpenDialog läst du den User nur die Zieldatei auswählen. Die dahinterstehende Lade/Speicherfunktion must du in jedem Fall selber schreiben. Also schau wie von mir gesagt in die Builder-FAQ in die TOP 3 der Fragen!

    bis bald
    akari



  • Also speichern:

    TStringList *list = new TStringList(); 
    list->Add(MeinString); 
    list->SaveToFile("c:\\test.txt"); 
    delete list;
    

    Werde ich gleich mal testen, und wie lade ich ihn dann wieder?

    Danke
    Max



  • Hallo

    sieh dir in der BCB-Hilfe die Eigenschaften TStringList::ItemCount und TStringList::Strings[] an. Und natürlich die Methode LoadFromFile().
    Auch im Forum suchen kann nichts schaden.

    bis bald
    akari



  • Hallo

    Habs so versucht:

    TStringList *list = new TStringList(); 
    list->Add(ma); 
    list->SaveToFile("daten.dat"); 
    delete list;
    

    Bekomme folgenden fehler:

    [C++ Fehler] Unit1.cpp(175): E2034 Konvertierung von 'person *' nach 'AnsiString' nicht möglich
    [C++ Fehler] Unit1.cpp(175): E2342 Keine Übereinstimmung des Typs beim Parameter 'S' ('const AnsiString' erwartet, 'person *' erhalten)
    

    Also die structur für das array heißt person, das array selber ma.

    Was mach ich falsch?

    Danke
    Max



  • Hallo

    TStringlist::Add() erwartet einen AnsiString als Parameter. Du must also die einzelnen Teile deines structs schon manuell als AnsiString entweder jedes in eine neue Zeile oder alle Teile, durch ein Steuerzeichen wie ';' oder '\t' getrennt, in eine Zeile speichern.

    bis bald
    akari



  • Hi!

    Also daraus werd ich nicht schlau 😞

    Kann mir mal jemand weiterhelfen?

    Danke
    Max



  • Hallo,

    Verrate uns doch mal was person ist (Deklaration der struct). Dann geht das mit der Hilfe ja vielleicht einfacher.
    Man könnte ja dieser Struktur (oder Klasse) die entsprechenden read/write Funktionen geben und sie sich selbst schreiben lassen.



  • Guten Morgen!

    Also das array sieht so aus:

    struct person { char name[20],
                         vorname[20],
                         handy[20];
                    int  personalnummer,
                         id;
                    float gehalt;
                  } ma[50] ;
    

    read/write funktion?

    Grüße
    Max



  • Man könnte der struct zwei Funktionen spendieren, eine die aus den Daten einen String erzeugt und eine, die den String wieder in Daten zerlegt.
    Das könnte so aussehen:

    AnsiString Person::GetAsString(void)
    {
    	AnsiString asResult;
    	AnsiString asTrennzeichen = "\t";
    	asResult = AnsiString(name);
    	asResult += asTrennzeichen;
    	asResult += AnsiString(vorname);
    	asResult += asTrennzeichen;
    	asResult += AnsiString(handy);
    	asResult += asTrennzeichen;
    	asResult += AnsiString(personalnummer);
    	asResult += asTrennzeichen;
    	asResult += AnsiString(id);
    	asResult += asTrennzeichen;
    	asResult += AnsiString(gehalt);
    };
    
    void Person::SetFromString(AnsiString asString)
    {
    	AnsiString asTemp;
    	AnsiString asTrennzeichen = "\t";
    	int Pos;
    	pos = asString.AnsiPos(asTrennzeichen);
    	if (pos)
    	{
    		strcpy(name, asTemp.SubString(1, pos).c_str();
    		asTemp = asTemp.Delete(1, pos);
    	}
    	pos = asString.AnsiPos(asTrennzeichen);
    	if (pos)
    	{
    		strcpy(vorname, asTemp.SubString(1, pos).c_str();
    		asTemp = asTemp.Delete(1, pos);
    	}
    	pos = asString.AnsiPos(asTrennzeichen);
    	if (pos)
    	{
    		strcpy(handy, asTemp.SubString(1, pos).c_str();
    		asTemp = asTemp.Delete(1, pos);
    	}
    	pos = asString.AnsiPos(asTrennzeichen);
    	if (pos)
    	{
    		personalnummer = asTemp.SubString(1, pos).ToInt();
    		asTemp = asTemp.Delete(1, pos);
    	}
    	pos = asString.AnsiPos(asTrennzeichen);
    	if (pos)
    	{
    		id = asTemp.SubString(1, pos).ToInt();
    		asTemp = asTemp.Delete(1, pos);
    	}
    	gehalt = asTemp.SubString(1, pos).ToDouble();
    };
    

    Wobei die GetFromString-Funktion auch als überladener Konstruktor Sinn machen würde. Das Ganze ist nur dahingetippt und enthält möglicherweise Fehler.
    Des weiteren habe ich komplett auf Fehlererkennung und -behandlung verzichtet. Wenn z.B. ein leerer String an die Methode GetFromString übergeben wird, sollte gar nicht erst versucht werden, daraus Daten zu ermitteln. Weiterhin fehlt jegliche Bereichsüberprüfung beim strcpy. Gibt also noch reichlich zu tun...
    Das soll Dir mehr einen Eindruck vermitteln, was zu tun ist. Das Ganze würde auch in ähnlicher Art und Weise mit TFileStream, statt TStringList funktionieren.



  • Hallo,

    Ich dachte eher an so etwas

    struct person 
    { 
      char name[20],
           vorname[20],
           handy[20];
      int  personalnummer, id;
      float gehalt;
      std::ostream& write(std::ostream& out) const;
      std::istream& read(std::istream&  in);
    };
    
    ostream& person::write(ostream& out) const
    {
        out.write(name, 20);
        out.write(vorname, 20);
        out.write(handy, 20);
        out.write((char*)&personalnummer, sizeof(personalnummer));
        out.write((char*)&id, sizeof(id));
        out.write((char*)&gehalt, sizeof(gehalt));
    }
    
    istream& person::read(istream&  in)
    {
        in.read(name, 20);
        in.read(vorname, 20);
        in.read(handy, 20);
        in.read((char*)&personalnummer, sizeof(personalnummer));
        in.read((char*)&id, sizeof(id));
        in.read((char*)&gehalt, sizeof(gehalt));
    }
    
    // Das könnte man dann so verwenden
    
    const int MENGE = 50;
    person test[MENGE];
    ... // irgendwie füllen
    
    // rausschreiben
    ofstream out("test.hhh");
    for( int i=0; i<MENGE; ++i)
       test[i].write(out);
    

    Sowas natürlich nur wenn die Struktur der Datei keine Rolle spielt. Wenn die Datei lesbar sein soll, dann eher die Art von Joe.



  • Guten morgen!

    Bekomm immer deklarations/syntax fehler...

    Habe mal mein programm und die vorlage hochgeladen, vll versteht man dann mein problem bissel besser:

    http://rapidshare.de/files/8079716/Winmax.zip.html
    Leider auf so nen anbieter, weil ich gerade im büro sitze und mir der proxy keine ftp-verbindung zulässt... mehr rechte bekommt mal als Azubi nicht...

    Gruß
    Max



  • Oder besser gefragt: womit mach ich mir die sache einfacher?

    Danke
    Max



  • Komme einfach nicht weiter...

    habe sämtliche möglichkeiten ausprobiert, aber keine bringt mich wirklich zum erfolg...

    Keiner mehr eine idee?

    Gruß
    Max



  • Kannst du mal den relevanten Teil (inklusive Fehlermeldungen) direkt hier posten? (mit dem angegebenen Link kann ich nicht wirklich etwas anfangen bzw. finde dort deine Datei vor lauter Werbung nicht)



  • machen wir es doch einfach mit streams

    ofstream out();
    ifstream in();

    und dann halt funktionen
    ich schau mir das prog mal an



  • Der Max hi hi !!!!
    Manuelmehlbeer@web.de



  • http://rapidshare.de/files/8387787/mitarbeiter.rar.html

    da könnt ihr es runterladen
    mit borland 6 kreirt.. jaja, die dummen tai's schaffen auch was....

    habe das problem mit fstreams gelöst..
    filein und fileout...
    ist doch net schwer 🙂

    liebe grüße

    T I M
    king-fred@web.de



  • schade.
    meldet sich ja keiner und kritisert mich schlecht und das gesdchaffene 🙂



  • zu einem nen dicken pluspunkt dafür, dass im archiv wirklich mal nur die nötigen quellcode-dateien liegen und kein schlotter wie die temporären dateien. 👍

    allgemein zum programm...

    - bei messageboxen immer die windows-konstanten verwenden, keine ahnung was die 16 bedeutet ohne das programm auszuführen oder in die quellheader zu gucken. 😞

    - was ist, wenn es mal 51 mitarbeiter werden?
    - keine globalen variablen wenn es nicht unbedingt nötig ist
    - code-formatierung ist unter aller sau.
    - in schleifen gehören keine variablen rein

    // die würde ich davor schreiben, sonsts wird bei jedem schleifendurchlauf
    // der speicher fuer die char-array reserviert.
    for(int i=0 ; i<50 ; i++)
    {
      char name[20];
      char vorname[20];
      char handy[20];
      int  personalnummer;
      float gehalt;
    //...
    

    - wusste gar nicht, dass so etwas funktioniert...

    // vergleich eines strings mit einer zahl
    if (gehaltEdit->Text >= 99999 || gehaltEdit->Text < 1)
    

    ach... könnte klappen, die zahl wird sicher vorher in nen String konvertiert und dann per Stringvergleich verglichen... äks.... ganz schlecht.

    - beim speichern, gibts es keinen default-dateinamen!
    - nach dem einlesen der daten stehen die in umgekehrter reihenfolge in der liste.
    - das löschen funktioniert nicht!

    reicht das für's erste? 😉



  • hallo.
    also variabvlen in schleifen geht wohl - denn bei jedem dchleifen durchgang wird sie zwar neu erstellt aber nur so lange sie auch existiert. ist doch genauso wie bei funktionen. sprich - es wird 50 mal neu gemacht und 50 mal gelöscht.
    [quote="Sunday"][/qoute]
    code-formatierung ist unter aller sau. [/qoute]
    richtig.
    -aber das wollte ich dann nicht auch noch machen. ich ahbe ihm aj auch kommentare reingeschrieben

    [quote="Sunday"]

    bei messageboxen immer die windows-konstanten verwenden, keine ahnung was die 16 bedeutet ohne das programm auszuführen oder in die quellheader zu gucken.
    [/qoute]
    -verstehe ich net?!
    ich benutze meisten ShowMEssage(""); nur bei abfargen die messagebox;
    aber ich galueb 16 stehet für bestimmte knöppe

    [quote="Sunday"]

    keine globalen variablen wenn es nicht unbedingt nötig ist [/qoute]
    -immer so loka wie mögluch (oder so public). aber er hatte es ja schon vorher so defineirt - daher habe ich es net gemacht.

    [quote="Sunday"]

    - wusste gar nicht, dass so etwas funktioniert...
    C/C++ Code:
    // vergleich eines strings mit einer zahl
    if (gehaltEdit->Text >= 99999 || gehaltEdit->Text < 1)
    [/qoute]
    also meiner meinung nach get das net wirklich - weil man es so machen müßte
    if (gehaltEdit->Text.ToInt() >= 99999 || gehaltEdit->Text.ToInt() < 1)

    und mit der konvertierung des strings müßte man es aber dann so schreiben "9999". weil er sonst den ausdruck nciht als string nimmt.
    ICH habe mich acuh nur aufs speichern konzentriert und vernünftige namen den komponenten gegeben

    [quote="Sunday"]
    beim speichern, gibts es keinen default-dateinamen! [/qoute]
    ja und? dass kann er machen - ich hatte no bock da jetzt noch nen filter einzuabuen 😃

    und zum löschen!? hmm. keine ahnung. das hatte ich net getestet. habe ich da etwa kot verschwinden lassen?

    mit dem einlesen... hmmm dann muss ich sie rückwärts abspeichern...

    das darf dann der verfasser machen.... Tipp
    mit schleife bis an den ersten eintrag von hinten gehen und ab dann speichern mit rückwärts forschleifen

    liebe grüße

    der ultra n00b


Anmelden zum Antworten