komplettes struct mit fprintf in Datei schreiben?



  • Wieso machst du das ganze mit fprintf,FILE,fopen ... etc.?
    Willst du es so machen oder musst du???

    Ich würde es ganz einfach mit open write read und close machen!

    Datei öffnen:

    int Datei = open ("computer_daten.dat",O_RDWR | O_CREAT | O_BINARY, 0666);
    

    in Datei schreiben,(in deinem fall dass struct pc_datenbank):

    write(Datei,&pc_datenbank,sizeof(pc_datenbank));
    

    und später wieder genau gleich aus der Datei ins struct pc_datenbank laden:

    read(Datei,&pc_datenbank,sizeof(pc_datenbank));
    

    und zum schluss:

    close(Datei);
    

    fertig!

    mfg hohesC 🙂

    [edit]io.h und fcntl.h sind zu includeieren[/edit]



  • PAD schrieb:

    sowie es ein \n für eine neue Zeile gibt, gibt es auch eine Zeichen für formfeed

    Escape Sequence Represents
    \a Bell (alert)
    \b Backspace
    \f Formfeed
    \n New line
    \r Carriage return
    \t Horizontal tab
    \v Vertical tab
    \' Single quotation mark
    \" Double quotation mark
    \\ Backslash
    \? Literal question mark
    \ooo ASCII character in octal notation
    \xhhh ASCII character in hexadecimal notation

    1. Wenn du in einem Dos-Fenster arbeitest nicht
    2. Wenn du das ganze in einer Windowsapplikation machst bieten sich Listboxen an
    3. Das sinnvolle Gegenstück zu fprintf ist fgets (oder fscanf) Jedes C-Buch bietet genügend Informationen zum lesen eines Files an. (z.B auch unter Behandlung von while Schleifen) oder schau dich hier im forum um (file lesen)

    Morgen PAD 🙂

    Ich habe die Escape-Sequenz für Formfeed schon ausprobiert, aber leider hat es nicht funktioniert. Es wird doch genauso mit printf() ausgegeben, wie z.B. \n, oder?

    Werde mich mal zu fgets informieren. Wenn es klappt, dann poste ich es hier.

    Ist es eigentlich sinnvoller die Daten binär oder im Textmodus in die Datei zu schreiben?

    Vielen Dank für deine Hilfe 🙂



  • hohesC schrieb:

    Wieso machst du das ganze mit fprintf,FILE,fopen ... etc.?
    Willst du es so machen oder musst du???

    Ich würde es ganz einfach mit open write read und close machen!

    Datei öffnen:

    int Datei = open ("computer_daten.dat",O_RDWR | O_CREAT | O_BINARY, 0666);
    

    in Datei schreiben,(in deinem fall dass struct pc_datenbank):

    write(Datei,&pc_datenbank,sizeof(pc_datenbank));
    

    und später wieder genau gleich aus der Datei ins struct pc_datenbank laden:

    read(Datei,&pc_datenbank,sizeof(pc_datenbank));
    

    und zum schluss:

    close(Datei);
    

    fertig!

    mfg hohesC 🙂

    [edit]io.h und fcntl.h sind zu includeieren[/edit]

    Hallo hohesC 🙂

    Was ist denn der Vorteil deiner Variante gegenüber meiner (abgesehen von weniger Code)?
    Also es ist nicht festgeschrieben wie ich es mache, es war halt die Variante die ich bereits kannte.
    Auf jeden Fall habe ich deine Methode mal ausprobiert, aber mein Compiler meldet mir "undefined identifier 'O_RDWR', 'write' und 'close'.
    was für eine header-Datei muss ich hierfür includen? Könnte aber auch an meinem Compiler liegen. Zu Hause benutze ich Borland, aber zur Zeit bin ich auf Arbeit und hier benutze ich so einen spartanischen MS-DOS Compiler.

    Danke 🙂



  • Aleks schrieb:

    Ich habe die Escape-Sequenz für Formfeed schon ausprobiert, aber leider hat es nicht funktioniert. Es wird doch genauso mit printf() ausgegeben, wie z.B. \n, oder?

    try this out:

    clrscr();

    vorher conio.h includieren.



  • io.h und fcntl.h sind zu includeieren



  • du schreibst mit write das gesamte struct in eine Datei
    und liest es mit read ganz einfach wieder aus und hast es wieder 100% identisch wie vorher in deinem struct, kannst es bearbeiten etc. einfacher gehts doch nicht!?

    mfg hohesC



  • Hallo ALEKS
    - Das Formfeed sollte wie \n funktionieren

    - wenn du auf einem PC in einer DOS-Box oder auf einem DOS-PC arbeitest, funktioniert das mit clrscr(), sonst nicht.

    - ich ziehe textbasierte Lösungen vor. siehe unten
    ---------------------------------------------------
    Hallo Hohes C

    Wie du weiter oben siehst, hat er eine adequate Lösung mit fwrite schon selber überlegt, ist dann aber wieder zu einer HRM (human readable material) Lösung zurückgekehrt. Aus meiner Sicht ist so eine ASCII Lösung gerade für solche Projekte deutlich übersichtlicher als eine Binäre Lösung, die dann meist auch noch CPU-abhängig (little/big endian) ist.

    Wenn man bedenkt das ganze Betriebssysteme mit solchen ASCII-Datein konfiguriert und gesteuert werden sind sie für mich sinnvoller als binär Dateien.

    Die meisten meiner Lösungen basieren ebenfalls auf ASCII-Dateien. Binäere Datein benutze ich nur dann, wenn es deutlich Performance Vorteile gibt, oder die Binäerdateien für große Files (>10MB) deutlich kleiner als ASCII-Dateien sind.

    ASCII-Datein, sind speziell bei Programmabstürzen oftmals besser zu retten als Binaerdateien.
    Während der Entwicklungsphase sind sie auch viel hilfreicher als binäre. Kommen
    Informationen hinzu kann man diese oftmals in bestehende Files "per Hand" nachrüsten. Bei Binäerdateien muß ich mir einen Konverter schreiben.

    😃



  • PAD schrieb:

    Hallo ALEKS
    - Das Formfeed sollte wie \n funktionieren

    - wenn du auf einem PC in einer DOS-Box oder auf einem DOS-PC arbeitest, funktioniert das mit clrscr(), sonst nicht.

    - ich ziehe textbasierte Lösungen vor. siehe unten
    ---------------------------------------------------
    Hallo Hohes C

    Wie du weiter oben siehst, hat er eine adequate Lösung mit fwrite schon selber überlegt, ist dann aber wieder zu einer HRM (human readable material) Lösung zurückgekehrt. Aus meiner Sicht ist so eine ASCII Lösung gerade für solche Projekte deutlich übersichtlicher als eine Binäre Lösung, die dann meist auch noch CPU-abhängig (little/big endian) ist.

    Wenn man bedenkt das ganze Betriebssysteme mit solchen ASCII-Datein konfiguriert und gesteuert werden sind sie für mich sinnvoller als binär Dateien.

    Die meisten meiner Lösungen basieren ebenfalls auf ASCII-Dateien. Binäere Datein benutze ich nur dann, wenn es deutlich Performance Vorteile gibt, oder die Binäerdateien für große Files (>10MB) deutlich kleiner als ASCII-Dateien sind.

    ASCII-Datein, sind speziell bei Programmabstürzen oftmals besser zu retten als Binaerdateien.
    Während der Entwicklungsphase sind sie auch viel hilfreicher als binäre. Kommen
    Informationen hinzu kann man diese oftmals in bestehende Files "per Hand" nachrüsten. Bei Binäerdateien muß ich mir einen Konverter schreiben.

    😃

    Hallo PAD 🙂

    das mit dem Formfeed funktioniert leider nicht. An der Stelle, wo eine neue Seite angezeigt werden sollte, wird einfach das Symbol für weiblich angezeigt 😕

    @hohesC:
    Wozu braucht man in deiner Methode eigentlich noch pc_datenbank? Als Pointer kann man es laut deiner Methode gar nicht benutzen, oder wie kann ich das verstehen?

    Danke für eure Hilfe 🙂



  • das ist der name des structs
    ich hab das struct einfach mal pc_datenbank genannt!

    struct daten 
    { 
     char name[15]; 
     int raum; 
     char benutzer[20]; 
     char login_zeit[20]; 
    } pc_datenbank;
    

    änder pc_datenbank in den namen deines structs! ich glaub computer heist dein struct!

    mfg hohesC



  • hohesC schrieb:

    das ist der name des structs
    ich hab das struct einfach mal pc_datenbank genannt!

    struct daten 
    { 
     char name[15]; 
     int raum; 
     char benutzer[20]; 
     char login_zeit[20]; 
    } pc_datenbank;
    

    änder pc_datenbank in den namen deines structs! ich glaub computer heist dein struct!

    mfg hohesC

    So, das habe ich jetzt auch getestet. Allerdings ist mir ein Problem aufgefallen. Bei jedem neuen Speichern in die Datei werden die alten Daten überschrieben.

    Gibt es da irgendeine Möglichkeit das zu verhindern?

    Danke 🙂



  • ja!
    mit

    lseek(Datei,0L,SEEK_END);
    

    springst du ans ende der datei und schreibst dort weiter!

    mfg hohesC



  • nimm für dein programm lieber ein struct array!

    struct daten 
    { 
     char name[15]; 
     int raum; 
     char benutzer[20]; 
     char login_zeit[20]; 
    } computer[100];
    

    dann musst du mit

    lseek(Datei,0L,SEEK_SET);
    

    immer auf den anfang springen um zu speichern.
    hast es dann aber alles identisch wieder im struct drinne und kannst es nach belieben bearbeiten.

    mfg hohesC



  • hohesC schrieb:

    ja!
    mit

    lseek(Datei,0L,SEEK_END);
    

    springst du ans ende der datei und schreibst dort weiter!

    mfg hohesC

    Wow, das ist ja der Hammer!
    Es funktioniert! Kann ich dem Prog mit lseek auch irgendwie sagen, dass er vom Anfang der Datei aus die Daten ausgeben soll? Sonst zeigt er mir immer nur den ersten Eintrag an.

    Danke für deine super Hilfe. Wieso gibt es eigentlich zum Öffnen, Schreiben und Lesen von Dateien so viele Möglichkeiten? 😕



  • guck mal eins über deinem post!
    das mit dem struckt array würde ich dir wie gesagt empfehlen, dann hast du sie wie schon erwähnt alle im struct und kannst nach belieben editieren.

    mfg hohesC



  • hohesC schrieb:

    guck mal eins über deinem post!
    das mit dem struckt array würde ich dir wie gesagt empfehlen, dann hast du sie wie schon erwähnt alle im struct und kannst nach belieben editieren.

    mfg hohesC

    Ok, werde mich heute abend darin vertiefen. Bin noch auf Arbeit und kann leider jetzt nicht weitermachen. Aber nochmals vielen Dank für deine Hilfe. Sobald ich es ausprobiert habe, werde ich die Ergebnisse hier melden.

    MfG 🙂



  • hohesC schrieb:

    nimm für dein programm lieber ein struct array!

    struct daten 
    { 
     char name[15]; 
     int raum; 
     char benutzer[20]; 
     char login_zeit[20]; 
    } computer[100];
    

    dann musst du mit

    lseek(Datei,0L,SEEK_SET);
    

    immer auf den anfang springen um zu speichern.
    hast es dann aber alles identisch wieder im struct drinne und kannst es nach belieben bearbeiten.

    mfg hohesC

    Hallo hohesC 🙂

    Bin leider auf ein paar Probleme gestoßen.
    Habe jetzt folgendes struct array:

    struct daten
    {
     char name[20];
     char raum[10];
     char benutzer[20];
     char login_zeit[20];
    } computer[100];
    

    Wenn ich nun mehrere Daten aus der Datei lesen möchte, habe ich jetzt eine for-Schleife gebaut. Hier gibt es nun 2 Probleme:
    1. Wie kriege ich raus, wieviele structs in meiner Datei stehen? Die Zahl ist nötig für die Zählvariable der for-Schleife.
    2. Wie mache ich bei der Ausgabe klar, dass das Prog für die Zählvariable i den entsprechenden Index einsetzt, um die gewünschten structs anzusprechen?

    Hier meine for-Schleife:

    for(i=0; i<="Anzahl der structs?"; i++) {
    read(Datei,&computer,sizeof(computer));
    printf("\n\n%s\n", computer[i].name);
    printf("%s\n", computer[i].raum);
    printf("%s\n", computer[i].benutzer);
    printf("%s\n", computer[i].login_zeit);
    }
    

    Hoffe mal, ich habe mich verständlich genug ausgedrückt.
    Danke für deine Hilfe 🙂



  • Also den 2. Punkt habe ich jetzt hinbekommen. ich bräuchte nur noch mal Hilfe beim Zählen der Elemente, damit ich der Zählvariable ein Limit setzen kann. Ansonsten läuft der Array zu oft durch und der letzte Eintrag wird einfach so oft wiederholt, bis die bedingung nicht mehr stimmt, oder aber sie wird zu wenig ausgeführt.

    Bitte um eure Hilfe, ist sehr wichtig für mich!

    Danke an Alle 🙂



  • Du benutzt eine binäre Datei, du kannst auch andere Informationen darin speichern.
    Eine Frage ist computer das gesamte Feld oder ist computer ein Element des Feldes. Falls computer ein Element ist ginge folgende Lösung

    Das nötigen Codeausrisse sehen dann so aus: (Bitte des Fehlerhandling nicht vergessen)

    #define Feldlänge 100
    typedef struct
    {
     char name[15];
     int raum;
     char benutzer[20];
     char login_zeit[20];
    } DatenSTRUCT;
    ....
    DatenSTRUCT computer[Feldlänge];
    int AnzElemente;
    ....
    // Dump der gesamten Datei
    lseek(Datei,0L,SEEK_SET);
    read(Datei,&AnzElemente,sizeof(int));
    if (AnzElemente > Feldlänge)
    {
    // Fehlermeldung Mehr Elemente im File Als reservierter Speicher
    }
    for(i=0; i<=AnzElemente; i++) 
    {
    read(Datei,&(computer[i]),sizeof(DatenSTRUCT));
    printf("\n\n%s\n", computer[i].name);
    printf("%s\n", computer[i].raum);
    printf("%s\n", computer[i].benutzer);
    printf("%s\n", computer[i].login_zeit);
    }
    .....
    //Das Schreiben der gesamten Datenbank
    //Schreiben der Anzahl an den Anfang der Datei
    lseek(Datei,0L,SEEK_SET);
    write(Datei,AnzElemente,sizeof(int));
    //Schreiben der gesamten Daten
    for(i=0; i<=AnzElemente; i++) {
    write(Datei,&(computer[i]),sizeof(DatenSTRUCT));
    .........
    //um einen beliebigen Record an Position Pos zu überschreiben
    lseek(Datei,sizeof(int)+(Pos*sizeof(DatenSTRUCT),SEEK_SET);
    write(Datei,computer[Pos],sizeof(DatenSTRUCT));
    ..........
    //um einen beliebigen Record an Position Pos zu lesen.
    lseek(Datei,sizeof(int)+(Pos*sizeof(DatenSTRUCT),SEEK_SET);
    read(Datei,&AnzElemente,sizeof(int));
    ..........
    //um einen neuen DatenRecord ans Ende anzuhängen
    lseek(Datei,0L,SEEK_END);
    write(Datei,&NeueDaten,sizeof(DatenSTRUCT));
    Dann wieder an den Anfang der Datei und die Anzahl aktualisieren.
    lseek(Datei,0L,SEEK_SET);
    write(Datei,AnzElemente,sizeof(int));
    ........
    

Anmelden zum Antworten