StringGrid - komplett abspeichern/einlesen



  • Hallo,
    ich bin Anfänger in C++ und möchte als Schulprojekt eine kleine CD-Verwaltung programmieren. Dazu würde ich gerne eine komplette Tabelle eines StringGrid in einer Datei speichern und auch wieder auslesen. Mit hilfe der Borland-Hilfe habe ich es nun geschafft die Zeilen-/Spaltenanzahl und die Strings in der Tabelle in eine Datei zu schreiben. Nun schaffe ich es aber nicht ganz diesen Quellcode so umzuschreiben, das die Werte auch wieder in die korrekte Zelle der Tabelle geschrieben werden. Hier sind noch meine beiden Quellcode für einlesen/ausgeben. Wäre nett wenn mir da jemand weiterhelfen könnte.

    [snip]

    Ich habe das ganze vorher mit diesen Funktionen versucht:
    Laden:
    StringGrid1->Rows[StringGrid1->Row]->LoadFromFile("\\cds.txt");

    Speichern:
    StringGrid1->Rows[StringGrid1->Row]->SaveToFile("\\cds.txt");

    Aber damit überschreibt er mir immer die Datei sobald eine neue Zeile gespeichert wird. Gibt es vielleicht eine Möglichkeit das umzuschreiben?

    cu
    Patrick www.mp3-fiesta.de

    [ Dieser Beitrag wurde am 04.01.2002 um 18:56 Uhr von Jansen editiert. ]



  • Ist doch klar, dass es nicht so funktionieren kann. SaveToFile kann keinen Fileappend. Musst Dir halt ne entsprechende Speicher-/Ladefunktion selber schreiben. So schwierig ist das doch nicht. Hier ein kleiner Lösungsvorschlag 😉

    Speichern eines StringGrids:

    FILE *fp;
    int row, rowcount;
    
    rowcount=StringGrid1->RowCount;
    
    // Datei zum Schreiben öffnen
    if((fp=fopen("c:\\Data.txt", "w"))==NULL)
    {   ShowMessage("Datei konnte nicht geöffnet werden");
        return;
    }
    // Header und Anzahl Zeilen/Spalten schreiben
    fprintf(fp, "StringGridData\n%d\n%d\n", rowcount, StringGrid1->ColCount);
    
    // Griddaten schreiben
    for(row=0; row<rowcount; row++)
    {   fputs(StringGrid1->Rows[row]->CommaText.c_str(), fp);
        fputc('\n', fp);
    }
    
    fclose(fp);
    

    StringGrid laden:

    #define SIZEOF_BUFFER 1024
    FILE *fp;
    int row;
    char *buffer=new char[SIZEOF_BUFFER];
    
    // Datei zum Lesen öffnen
    if((fp=fopen("c:\\Data.txt", "r"))==NULL)
    {   ShowMessage("Datei konnte nicht geöffnet werden");
        delete buffer;
        return;
    }
    
    // Header einlesen und prüfen ob die richtige Datei vorliegt
    fgets(buffer, SIZEOF_BUFFER, fp);
    if(memcmp(buffer, "StringGridData", 14)!=0)
    {   ShowMessage("Keine StringGrid Datendatei !");
        fclose(fp);
        delete buffer;
        return;
    }
    
    // Anlahl Rows einlesen und in StringGrid setzen
    fgets(buffer, SIZEOF_BUFFER, fp);
    StringGrid1->RowCount=atoi(buffer);
    
    // Anlahl Cols einlesen und in StringGrid setzen
    fgets(buffer, SIZEOF_BUFFER, fp);
    StringGrid1->ColCount=atoi(buffer);
    
    // Griddaten einlesen
    for(row=0; fgets(buffer, SIZEOF_BUFFER, fp); row++)
        StringGrid1->Rows[row]->CommaText=buffer;
    
    fclose(fp);
    delete buffer;
    

    [ Dieser Beitrag wurde am 01.01.2002 um 22:20 Uhr von Peter editiert. ]



  • Ahem, ich denke wir sind hier im VCL-Forum, oder nüch? 😉

    // StringGrid speichern
    
    // Liste, die das Abbild des StringGrids enthalten wird
    TStringList *list = new TStringList();
    
    // Spaltenzahl speichern
    list->Add(StringGrid1->ColCount);
    
    // Werte zeilenweise in die Liste übertragen
    for (int y = 0; y < StringGrid1->RowCount; y++)
       list->Add(StringGrid1->Rows[y]->CommaText);
    
    // Liste in Datei speichern
    list->SaveToFile("c://test.txt");
    
    // nicht vergessen, den Speicher wieder freizugeben
    delete list;
    
    // StringGrid laden
    
    // Liste, die das Abbild der Datei enthalten wird
    TStringList *list2 = new TStringList();
    
    // Liste aus Datei laden
    list2->LoadFromFile("c://test.txt");
    
    // Zeilen- und Spaltenzahl setzen
    StringGrid2->RowCount = list2->Count - 1;
    StringGrid2->ColCount = list2->Strings[0].ToInt();
    
    // Werte zeihlenweise aus der Liste übertragen
    for (int y = 1; y < list2->Count; y++)
       StringGrid2->Rows[y - 1]->CommaText = list2->Strings[y];
    
    // nicht vergessen, den Speicher wieder freizugeben
    delete list2;
    


  • :):):) @Jansen
    Klar geht das so auch ...
    VCL heisst aber nicht, dass man mit aller Gewalt VCL Kompos verwenden muss, oder ? [img]images/smiles/icon_wink.gif[/img]
    Warum denn alles nochmal innen Speicher lutschen bzw. zusammenstellen und dann erst schreiben, wenn man das gleich erledigen kann ? Microsoft ist doch schon dem (Haupt-) Speicherwahn verfallen, warum sollen wir dem mit aller Gewalt folgen :D:D:D



  • VCL heisst aber nicht, dass man mit aller Gewalt VCL Kompos verwenden muss, oder ?

    Doch, unbedingt!!! 😃

    Naja, ein Vorteil der StringList wäre noch , dass sie "exception safe" (?) ist, man also bequem mit try/catch arbeiten kann. Und das eingebaute Sortieren und Suchen kann man auch immer gebrauchen. 🙂

    Du siehst schon, ein Programmierer der alten Schule, der um jedes Byte kämpft wird aus mir nicht mehr. 😮 🙂



  • @Jansen
    Hast recht, es kommt imemr auf den einzelnen Fall drauf an.
    Ich hab halt noch auf einem 6502 mit 4kb Hauptspeicher geprogged, da konnte man nicht so grosszügig mitm Speicher umgehen. Irgendwie steckt das immer noch in mir drinnen 😃


Anmelden zum Antworten