Mehrere Strukturen Speichern und Auslesen



  • Hi alle,

    ich habe in der Suchfunktion nichts gefunden und bin aus den Seiten in google nicht wirklich schlauer geworden ...

    Ich habe das Problem, dass ich eine Schuelerdatenbank für mehrere Klassen machen möchte jede Klasse eine eigene Datei mit 40 Schülern. Ich möchte jetzt die Strukturen in den Dateien gespeichert habe wieder auslesen. Und weiß nicht wirklich wie das geht... Muss ich die ganze Struktur speichern, oder gibt es einen befehl, das er alle schueler speichert und ich die dann einfach wieder auslesen kann... oder muss ich alle Schuler einzeln speichern?

    Da wir in der Schule noch nicht so weit sind, dachte ihr könntet mir vielleicht helfen.

    Hier meine Struktur:

    struct Schuelermaske
        {
        AnsiString vorname;
        AnsiString nachname;
        AnsiString strasse;
        int        hausummer;
        AnsiString plz;
        AnsiString wohnort;
        AnsiString klasse;
        AnsiString schuleintritt;
        AnsiString gebdatum;
        AnsiString geburtsort;
        AnsiString icq;
        AnsiString email;
        int        schuelerindex;
      } schueler[40];
    

    Der Schuelerindex gibt an, an welcher Position der Schüler gespeichert werden soll,

    Also zum Beispiel:

    schueler[edt_schuelerindex->Text.ToInt()].vorname = "Hans";
    

    Ich arbeite mit Turbo C++ Explorer habe aber auch die 6er Version des Borland Builder zur verfügung.

    Vielen Dank schonmal im Voraus.
    MfG Disi



  • Hmm, wenn ich mich jetzt nicht ganz irre, dann geht es, wenn du das in etwa so machst:

    Schuelermaske schueler;
    Schuelermaske schueler2;
    ...
    
    std::ofstream out (std::ios::app);
    
    out << schueler;
    out << schueler2;
    ...
    

    Bin mir aber jetzt nicht mehr sicher, ob ich das richtig in Erinnerung habe, ob das geht.



  • Erstmal vielen dank für deine Antwort,

    Ich habe selber auch schon experimentiert und habe überlegt ob ich die Strukturen nicht in gewissen abständen eingeben lassen kann.

    Also, dass ich zum Beispiel immer die Struktur des Schülers mit dem schuelerindex 1 nach vorne packe und dann wenn ich z.B. einzelne Schüler aufrufen will nur die Indexnummer angeben muss und dann genau diesen Schüler aus der Datei laden kann.

    MfG Disaster



  • Das was du willst ist hier:

    http://www.cppreference.com/cppio/index.html

    Schau die dann auch mal seekg an. Da musst du hald alles selber noch kapseln, wenn du z.B einfach auf einen Schüler zugreifen willst.



  • Ich weiß, der Programmierstyle is nicht der Beste.

    frm_hauptfenster->datei[1].datei.open(frm_hauptfenster->datei[1].dateiname.c_str(), ios::binary | ios::out | ios::in);
    
    	frm_hauptfenster->datei[1].datei.seekg(sizeof(frm_hauptfenster->schueler)*edt_schuelerindex->Text.ToInt());
    	frm_hauptfenster->datei[1].datei.read((char*)&frm_hauptfenster->schueler[edt_schuelerindex->Text.ToInt()],sizeof(frm_hauptfenster->schueler));
    
    	frm_hauptfenster->datei[1].datei.close();
    

    aber so habe ich jetzt versucht es zu lösen, dass ich eine Struktur auslesen kann.
    Funktioniert nur, wenn ich das Programm nicht schließe, was meiner Meinung daran liegt, dass ich die Angaben noch in der Struktur gespeichert habe. Wie löse ich das Problem ? Hoffe, einer von euch hat eine Idee.

    MfG Disaster



  • schau dir ma mysql oder irgend nen ähnliche datenbanksysteme an... ist zwar meist nicht ganz einfach, ne lib dazu zu finden und zu kapieren, wie die funtzt, aber wenn man die dann erst ma gefunden hat ist es 1. schneller 2. bequemer 3. eleganter...

    ansonsten mach es doch, wie drakon es sagt:
    nutz den shift operator...

    typedef unsigned __int16 MYVAR;
    const MYVAR maxschueler (40);
    
     struct Schuelermaske
        {
        AnsiString vorname;
        AnsiString nachname;
        AnsiString strasse;
        int        hausummer;
        AnsiString plz;
        AnsiString wohnort;
        AnsiString klasse;
        AnsiString schuleintritt;
        AnsiString gebdatum;
        AnsiString geburtsort;
        AnsiString icq;
        AnsiString email;
        int        schuelerindex;
    /*TODO:
    operator >>
    implementieren
    */
    
    static void seekto (MYVAR indexnr, std::ifstream *stream)
    {
    stream->seekg (/*viel zu langer ausdruck ^^*/);
    };
      } schueler[maxschueler]; 
    
    //-----------------------------------------
    
    std::ifstream *stream = new std::ifstream (".\\dateinameimverzeichnisderexe.dateiendung", ios::out);
    /*
    binary würde ich nicht machen - sonst musst du ja auch noch nen prgramm (bzw ne fkt) schreiben,
    was die daten da reinschreibt - so kannst du das einfach auf den user abwälzen ;)
    nene - je nach dem, wie du es halt brauchst ^^
    */
    
    MYVAR i (0);
    for (i; i < maxschueler; ++i)
    {
    if (stream.good ())
    stream >> schueler[my_zaehlvariable];
    else break;
    }
    if (!stream.eof)
    {
    //fehler (bei nr. i)...
    // => nen throw oder return oder wie au immer..
    }
    else
    {
    //es wurden erfolgreich i datensaetze ausgelesen...
    };
    
    delete stream;
    

    ansonsten könntest du dir auch mal std::vector angucken - da haste keine so statischen arrays...

    bye

    //edit:
    anscheind nutzt du ja bcb... kein plan, was der unterschied zwischen AnsiString und std::string ist - aber ich würde definitiv std::string nehmen - so biste ne so an BCB gebunden... zumindest in der fkt ne, weil du ja anscheind au ne gui hast ^^

    nr.2:
    ich seh gerad noch was:

    int        hausummer;
    /*
    struct hausnummer
    {
    unsigned __int16 nr; //65535 reicht ^^
    char eins; //für das a, b, .... was ab und an hinter ner hausnr. zu finden ist...
    }
    */
        AnsiString plz;
    /*=> mach nen unsigned __int16 draus... die fehlenden führenden 0en kannste ja mit ner fkt wieder ranmachen:
    (entweder du machst sie static in den struct rein oder du nimmst dir noch nen namespace names NSchuelermaske oder so was in der richtung
    std::string GetRightPLZfromINT (unsigned __int16 plz)
    {
    char R[6];
    for (unsigned __int i (5); i != 0; --i)
    {
    R[i] = plz%10 + '0';
    plz /= 10;
    }
    R[5] = 0; //oder = '\0' - geschmackssache...
    return R;
    }
    */
        AnsiString klasse; 
    /*
    würd ich evtl noch nen extra struct klasse machen:
    struct klasse
    {
    unsigned __int8 klassenstufe;
    char eins;
    char zwei;
    /*
    TODO:
    operator >>
    implementieren
    */
    std::string getnameasstring (void)
    {
    return (IntToStr (klassenstufe) + eins + zwei));
    }
    /*
    damit solltest du alles erfassen, was es an klassenbezeichnungen so gibt ^^
    das schlimmste, was ich ma gesehen hab, war 8b2
    */
    
    };
    */
        AnsiString schuleintritt;
    /*
    wahrscheinlich ein Jahr und max. noch ein Monat... ==>
    struct eintritt
    {
    unsigned __int16 jahr; //musst du eben im jahr 65536 ein update rausbringen - besser schon 65535 ^^
    enum monat
    {
    //jan-dez, falls du das brauchst ansonsten eben enum quartal oder lässt es ganz weg
    };
    }
    */ 
        AnsiString gebdatum; 
    /*
    hier gibts nat. viele möglichkeiten (timestamps und andere von windows bereitgestelle datums-structs etc ^^), aber ich würds trotzdem so machen:
    struct date
    {
    unsigned __int8 tag;
    enum monat;
    unsigned __int16 jahr;
    static bool isvaliddate (const date &datum)
    {
    //falls usereingaben dabei sind solltest du ja ma gucken, ob er vll 31.2. oder so eingibt ^^
    };
    };
    */
        AnsiString icq; 
    /*
    struct icq
    {
    unsigned __int32 nr;
    //da die nr. atm glaube noch 9stellig sind hast du hier auch noch bissl reserve ^^
    /*
    TODO:
    operator >>
    */
    /*
    TODO:
    vll noch ne fkt echo (parameter) => ausgabe mit oder ohne '-' oder leerzeichen oder wie au immer ^^
    */
    }
    */
        AnsiString email; 
    /*
    sollte reichen aber evtl noch nach nem @ suchen und nem . und wenn dus ganz toll machen willst, kannste noch versuchen, die url anzupingen ^^
    */
        int        schuelerindex;
    //=> MYVAR id;
    

    mir war langweilig, ich gebs ja zu ^^ hoffe, dir bringt das was und du überlegst vll mal, ob du es nicht doch noch ändern willst ^^



  • 😃 <- erste, was mir dazu eingefallen ist -> 😃

    Vielen vielen dank !!!

    Das problem ist .. ich habe grad mal Variablen und Strukturen d.h. nix mit Klassen, enum usw.
    und bei dem
    /*
    TODO:
    operator >>
    */

    weiß ich garnicht, was du damit meinst 😕

    Ich habe bei BCB es so gemacht, dass ich Edit-Felder mit einer Edit-Mask versehen habe, sodass ich von vornherrein schon bestimmte normen bei der Eingabe vorgegeben habe.

    Ich werde deinen Post aber auf jeden Fall mehr als einmal durcharbeiten müssen/wollen 😉

    Vielen Dank !



  • Huhu alle ^^

    Ich habr grad eben gemerkt, dass ja garnichts in der Datei steht ... jetzt habe ich das Problem, dass ich wahrscheinlich einen Fehler im Speichervorgang habe (naja ich habe auf jeden fall einen) Wie würdet ihr eine Struktur in einer Datei Speichern ?

    ich sitz hier schon den ganzen tag drann 😃 ich will das endlich schaffen ....

    MfG Disaster


Anmelden zum Antworten