komplettes struct mit fprintf in Datei schreiben?
-
PAD, is das nicht schon klar?
das problem beim schreiben ist, wenn das "b" fehlt, bestimmte zeichen (ein \r\n in ein \n) umgewandelt werden.
-
Meines wissens wirkt diese Spezialität der Microsoftwelt mit dem b nur beim fprintf/fputs statement. Das fwrite ist glaube ich nicht davon betroffen. Er dürfte bei seiner Struktur folgender "eigentümlichkeiten" sehen
- die \0 die die Strings beenden,
- die undefinierten Zeichen nach dem \0 bis zum Feldende,
- die Füllbytes
- die interne Darstellung der Integer Zahl als Int32
- glücklicherweise hat er keine floats/double dabei
-
Danke erstmal an Alle
Also, da der compiler gleich ist, das betriebssystem aber wechselt, habe ich es dann doch so gemacht:
printf("\n\nBitte geben Sie jetzt die Daten an:\n"); printf("\nPC-Name : "); gets(computer.name); printf("\nRaum : "); gets(computer.raum); printf("\nBenutzer : "); gets(computer.benutzer); printf("\nLogin-Zeit: "); gets(computer.login_zeit); FILE *pc_datenbank; pc_datenbank = fopen("archiv.txt","a"); fprintf(pc_datenbank, "\n__________________________________\n\n"); fprintf(pc_datenbank, "PC-Name: %s\n", computer.name); fprintf(pc_datenbank, "Raum: %s\n", computer.raum); fprintf(pc_datenbank, "Benutzer: %s\n", computer.benutzer); fprintf(pc_datenbank, "Login-Zeit: %s\n", computer.login_zeit); fclose(pc_datenbank);
Die von euch genannten Methoden haben auf jeden Fall auch funktioniert, aber da es sich hierbei um eine Schularbeit, die benotet wird, handelt, will ich mal lieber auf Nummer sicher gehen
Habe noch drei andere Fragen, für die ich keinen neuen Thread eröffnen wollte und auf die ich im Forum leider keine Antwort gefunden habe:
1. Wie kann ich eine leere Seite ausgeben? Ich möchte zum Beispiel einen Punkt aus meinem Hauptmenü wählen und das Ergebnis soll dann auf einer neuen Seite angezeigt werden, also am oberen Bildrand soll man das Hauptmenü nicht mehr sehen.
2. Ist es möglich, dass ich eine Art Scrollmechanismus einbaue, für den Fall das meine Datei irgendwann zu lang wird und nicht alle Ergebnisse auf den Bildschirm passen?
3. Kennt ihr vielleicht ein gutes Tutorial wo ich lesen kann, wie man einzelne Daten der Datei später wieder einlesen und bearbeiten kann?Hoffe mal, ihr habt eine Antwort auf meine Fragen oder lest sie wenigstens mal, ansonsten eröffne ich vielleicht doch noch einen neuen Thread
Vielen Dank an euch!
Dank diesem Forum habe ich schon eine Menge dazu gelernt
-
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 notation1. 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)
-
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 notation1. 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 CWie 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 CWie 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!
mitlseek(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!
mitlseek(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