dateien schreiben und lesen
-
hallo wie schon genannt sitz ich am problem binärdateien zu schreiben und wieder zu lesen.
ich habe eine struktur namens personen dort sind z.b name vorname alter gespeichertstruct personen { char Vname[20]; char Name[20]; int Alter; int Tel; } p1;
nun habe ich eine funktion geschrieben die diese struktur mit werten füllt
void eingabe_struct(struct personen *p1) { puts("Vname: "); scanf("%s",p1->Vname); fflush(stdin); puts("Name: "); scanf("%s",p1->Name); fflush(stdin); // Ausgabe von zahlen in der datei kommen iwie komische zeichen raus^^ puts("Alter: "); scanf("%d",&p1->Alter); fflush(stdin); puts("Tel.: "); scanf("%d",&p1->Tel); fflush(stdin); }
nun ist mein problem den vektorinhalt in eine datei zu schreiben
void datei_ausgabe(struct personen *p1,FILE *f)
{fwrite(p1,sizeof(*p1),1,f); // so hab ich es gelöst^^
}
void datei_oeffnen(void)
{
FILE *f;f=fopen("test.txt","wb+");
if(f==NULL)
{
puts("DateiOpen-Fehler!!");
}
else
{
datei_ausgabe(&p1,f);
fclose(f);
}exit(-1);
}
und dazu eine funktion die den dateiinhalt in den vektor einliestdanke
-
Hallo,
die Struktur wird genau so in die Textdatei geschrieben, wie sie im Speicher liegt und zwar byteweise. Beim Datentyp
char
gibt's da keine Probleme, bei den anderen schon.Mein Lösungsvorschlag wäre die Benutzung von
fprintf
:// in die Datei schreiben fprintf (f, "%-20s %-20s %d %d",p1.Vname, p1.Name, p1.Alter, p1.Tel); // aus der Datei lesen fscanf (f, "%20s %20s %d %d", p1.Vname, p1.Name, &p1.Alter, &p1.Tel);
Gez. monstermunchkin
-
// Ausgabe von zahlen in der datei kommen iwie komische zeichen raus^^
Das ist normal, wenn im Binärformat geschrieben wird, kein Problem.
-
tHaboss schrieb:
und dazu eine funktion die den dateiinhalt in den vektor einliest
dankedas selbe in grün mit fopen( "xx", "rb" ) und fwrite
bitte.0asfdaß
-
Du solltest lieber getchar statt scanf benutzen und zwei char* statt char[] in Kombination mit malloc benutzen. Wenn jemand einen Vor- oder Nachnamen mit mehr als 19 Zeichen hat ist deine Struktur futsch. Sowas nennt sich Pufferüberlauf: http://de.wikipedia.org/wiki/Pufferüberlauf und sollte auf jeden Fall vermieden werden.
Ich weiß auch nicht was genau du mit Vektor meinst.
Wenn du aus der Datei die Struktur wieder einlesen willst gibt es 2 Varianten.
1. Du lässt den Fehler in der Struktur stehen und benutzt
struct personen{ char Vname[20]; char Name[20]; int Alter; int Tel; } p1; const char* datei = "pfad/datei"; f = fopen(datei, "rb"); if (f) fread(&pl, sizeof(struct personen), 1, f); else printf("fehler beim lesen von %s\n", datei); fclose(f);
Oder du machst es richtig und schreibst sowas wie
struct personen{ char* Vname; char* Name; int Alter; int Tel; } p1; char *readline(FILE* f){ //lese eine Zeile Text ein char *buffer, *tempbuffer; int buffersize = 32, maxbuffersize = 1<<12; int i, t, fertiggelesen = 0; if (!buffer = malloc(buffersize)) exit(printf("Fehler: Speicher ist alle")); while (1){ for (i = 0; i<buffersize-1; i++){ t = fgetc(f); if (t==EOF) exit(printf("Datei %s ist kaputt\n", datei)); else buffer[i] = (char)t; if buffer[i] = '\n'{ //Zeile zuende buffer[i+1] = '\0'; tempbuffer = buffer; if (!buffer = malloc(strlen(tempbuffer)+1)) exit(printf("Fehler: Speicher ist alle")); strcpy(buffer, tempbuffer); free(tempbuffer); return buffer; } } //buffer hat nicht gereicht if (buffersize=<<1 > maxbuffersize) exit(printf("Fehler: Zeile in Datei %s ist zu lang\n", datei)); tempbuffer = buffer; if (!buffer = malloc(strlen(tempbuffer)+1)) exit(printf("Fehler: Speicher ist alle")); strcpy(buffer, tempbuffer); free(tempbuffer); } } const char* datei = "pfad/datei"; //laden FILE *f = fopen(datei, "r"); p1->Vname = readline(f); p1->Name = readline(f); p1->Alter = stringtoint(readline(f)); p1->Tel = stringtoint(readline(f)); fclose(f); //speichern: f = fopen(datei, "w"); fprintf(f, "%s\n%s\n%d\n%d\n", p1->Vname, p1->Name, p1->Alter, p1->Tel); fclose(f);
Fehlt noch die Mainfunktion und vielleicht sollte readline return 0 statt exit nutzen wenn es schief geht, und es ist natürlich nichts davon getestet, aber die Idee sollte klar sein. Ist natürlich aufwendiger alles, aber dafür funktioniert es immer oder sagt wieso es nicht geht statt eine Sicherheitslücke aufzureißen.
-
Die Arraygrenzen absichern sollte man schon, aber die größen der Arrays sind doch fest vorgegeben, malloc zu bemühen ist ein bisschen weit hergeholt.
Wenn man für das Einlesen einen Puffer wählt der groß genug ist, dann braucht man den Eingabepuffer nicht zu leeren, weil nix im Eingabepuffer übrig bleibt.char buf[BUFSIZ]; // BUFSIZ ist in stdio.h definiert und gibt die Größe des Eingabepuffers an.
Gruß,
B.B.
-
nwp2 schrieb:
Du solltest lieber getchar statt scanf benutzen und zwei char* statt char[] in Kombination mit malloc benutzen. Wenn jemand einen Vor- oder Nachnamen mit mehr als 19 Zeichen hat ist deine Struktur futsch. Sowas nennt sich Pufferüberlauf: http://de.wikipedia.org/wiki/Pufferüberlauf und sollte auf jeden Fall vermieden werden.
Man kann auch einfach nur 19 Zeichen einlesen:
... scanf ("%19s", p1.Vname); scanf ("%19s", p1.Name); ...
-
oda mit fgets begrenzen. fgets ist noch etwas flexibla!
-
danke für eure hilfe ich werde mich melden sobald neue problem auftreten oder wenn sich etwas ändern sollte^^
-
also ich hab mich wieder damit beschäftigt diesmal kam etwas effektives raus ^^
void main(void) { FILE *d; struct person vec[20]; // mein angelegter strukturvektor eingabe_struct(&p1); // struktur füllen ausgabe_struct(&p1); d=datei_oeffnen(); // datei im binärmodus zum schreiben öffnen datei_ausgabe(vec,d); //text in datei schreiben fclose(d); } void datei_ausgabe(struct person *vec,FILE *f) { int i=0; // Schleife //for(i=0;i<sizeof();++i); // gescheiterter versuch fwrite(&vec+i,sizeof(struct person),1,f); fprintf(f, "%s %s %d %d\n",p1.Vname,p1.Name,p1.Alter,p1.Tel); printf("\n\nLaenge: %d",i); } FILE* datei_oeffnen(void) //verändert { FILE *f; f=fopen("test.dat","w+b"); if(!f) { puts("DateiOpen-Fehler!!"); //exit(2); } return f; } void eingabe_struct(struct person *p1) { char c; do{ puts("Vname: "); scanf("%10[^\n]",p1->Vname); fflush(stdin); puts("Name: "); scanf("%10[^\n]",p1->Name); fflush(stdin); puts("Alter: "); scanf("%d",&p1->Alter); fflush(stdin); puts("Tel.: "); scanf("%d",&p1->Tel); fflush(stdin); printf("Ende (ENTER) oder bel. Eingabe "); }while ((c=getch())!='\r'); } void ausgabe_struct(struct person *p1) { printf("\nVorname: %s\n", p1->Vname); printf("Name: %s\n", p1->Name); printf("Alter: %d\n", p1->Alter); printf("Telefon: %d\n", p1->Tel); } mein problem ist halt wen ich jetz die datei öffne und den code krieg sieht das iwie komisch aus mit so häsligen zeichen^^ AUSGABE:
00000000 24 FD 12 00 48 14 31 10 62 FB 41 5F 91 5D CA 01 $...H.1.b.A_.]..
00000010 00 E0 FD 7F CC CC CC CC CC CC CC CC 66 65 6C 69 ............feli
00000020 78 20 6D 75 73 74 65 72 20 32 30 20 32 32 31 32 x muster 20 2212
00000030 0A
[cpp]ist das normal das vor meinem eigentlich eingegebenen text : felix muster 20 2212 solche komischen zeichen kommen ?
danke
thaboss
-
Hallo,
ist das normal das vor meinem eigentlich eingegebenen text : felix muster 20 2212 solche komischen zeichen kommen
Nein, aber du solltest dich schon entscheiden, ob du mit fwrite oder mit fprintf (dann musst du die Datei nicht binär mit +b öffnen) in die Datei schreiben willst. Dann ist auch noch ein "&" zu viel:
fwrite(vec+i,sizeof(struct person),1,f);
MfG,
Probe-Nutzer