verkettete Liste speichern/laden
-
ich meinte fgets, und im Anschluß einen kleinen Code-Ausriss für die Lese Routine, es ist noch eine von meinen Toolroutinen dabei.
Viel Spaß
#define BUFFERLEN 1024 char buffer0[BUFFERLEN+1]; char buffer1[BUFFERLEN+1]; // vname#nname#wohnort#plz#strasse#hausnummer#vorwahl#telnr\r\n fgets(buffer0,BUFFERLEN,ifp); // get one line if (feof(ifp)) // checking for end of file to finisch process break; // Buffer0 vname#nname#wohnort#plz#strasse#hausnummer#vorwahl#telnr\r\n substr(buffer0,buffer,'#'); // Buffer0 nname#wohnort#plz#strasse#hausnummer#vorwahl#telnr\r\n // Buffer1 vname //und das wiederhoöen solange bis du alle Elemente hast. /////////////////////////////////////////////////////////////// /***********************************************************************.FA* .FUNCTION [ gets the first part of a string loosing the delimiter ] -------------------------------------------------------------------------- .GROUP [ String ] .AUTHOR [ PAD /DDT ] -------------------------------------------------------------------------- .DESCRIPTION This routine copies all chars from the beginning of the string in to lowout until ist finds the delimiter. the delimiter gets skipped an the rest of the string is moved to in. That means that the first part of the string ist in lowout, the rest of the string is in except the delimiter -------------------------------------------------------------------------- .INDEX Utilities -------------------------------------------------------------------------- .PARAMETER CHANGED char * in rest of string OUT char * lowout first part of the string -------------------------------------------------------------------------- .RETURNVALUE 0 allways -------------------------------------------------------------------------- .VARIABLE_REFERENCES -------------------------------------------------------------------------- .HISTORY Date Author Comment 14.06.94 PAD /DDT Definition **********************************************************************.HE**/ int substr(char * in, char * lowout,char search) { char *highout; highout=in; while ( ( search != * in ) && ( * in ) ) *lowout++ = *in++; *lowout=0; if (0 != *in)in++; while ( * in ) *highout++= *in++; *highout=0; return 0; }
-
ok, ascii kann man per hand bearbeiten. das ist aber auch der einzige vorteil.
eine ascii datei zu parsen, ist komplizierter als nötig.
dein argument, man kann so besser erweitern, zieht schlecht,
weil beim parsen von neueren/älteren daten probleme aufkommen, wenn was fehlt.
-
Wenn man die Daten im File immer nur am Ende der Zeile erweitert, und das leseverfahren tolerant gegen fehlende Elemente am Ende auslegt ist das kein Problem.
Den Parser habe ich ja eigentlich schon gepostet und zwar sowohl zum schreiben als auch zum Lesen. Beim LeseVerfahren fehlt noch etwas vom Fehlerhandling aber sonst ist der eigentlich nicht so kompliziet.Fehlerhandling beim lesen von BinaerDateien muß auch sein, den fread liest hemmungslos die angegebene Anzahl von Bytes aus dem File und stopft diese ungesehen in die Struktur. Also must du eigentlich jedem Lesen zumindest eine Plausibiltätscheck nachfolgen lassen und schon haben wir die gleiche Komplexität.
D.h. mit einem Binärleser kannst du jedes File öffnen und jeden Blödsinn in die internen Daten stecken. Wenn sich jetzt durch eine absichtliche oder unabsichtliche Strukturänderung eine Kleinigkeit ändert, kann ich meine Daten nicht mehr sinnvoll lesen.
-
Kansst du mir das hier bitte mal erklären:
#define BUFFERLEN 1024 char buffer0[BUFFERLEN+1]; char buffer1[BUFFERLEN+1];
-
Diese Schreibweise habe ich mir angewöhnt, damit die üblichen Fehler mit der schließenden NULL eines C-Strings nicht passieren.
Typischerweise plant man einen String der Länge 80 um 80 Zeichen unterzubringen und vergisst dabei das 81. Zeichen für die schließende NULL, typischer Anfänger/flüchtigkeitsfehler.
-
Das trennen funktioniert, aber wie sage ich, dass ich in der nächsten Zeile weitermachen will!?
-
Ich verstehe nicht ganz was du meinst.
Wenn du die ganze Datei lesen willst müßte es ungefähr so aussehen
// // Funktion um eine Zeile auszuwerten // Input char * String mit den Daten // Output Struktur Typ PersSTRUCT gefüllt mit Datem // int ParseOneline(char *Buffer,PersSTRUCT *Data) { // Buffer vname#nname#wohnort#plz#strasse#hausnummer#vorwahl#telnr\r\n substr(Buffer,Data->vname,'#'); // Hier Plausibiltätscheck ob Daten gültig // Buffer nname#wohnort#plz#strasse#hausnummer#vorwahl#telnr\r\n substr(Buffer,Data->nname,'#'); // Hier Plausibiltätscheck ob Daten gültig if (0==strlen(Data->nname)) { printf("Nachname ist leer"); return 1; } // Buffer wohnort#plz#strasse#hausnummer#vorwahl#telnr\r\n .... return 0; // Alles Ok } //.... Ausriss aus dem Lesen eines Files //.... while(fgets(buffer0,BUFFERLEN,ifp) { // bereitstellen eines neuen Datenelements if (0==(Data=calloc(1,sizeof(PersSTRUCT))) { printf("calloc fehlgeschlagen"); break; } if (0!=ParseOneline(buffer0,Data)) { printf("Parser fehlgeschlagen"); break; } // Bereitstellen eines neuen Listenelements // Eintragen der Daten Personen->Daten=Data; } ...
-
Die Datei sieht ja wie folgt aus:
vname#nname#wohnort#plz#strasse#hausnummer#vorwahl#telnr
vname#nname#wohnort#plz#strasse#hausnummer#vorwahl#telnr
vname#nname#wohnort#plz#strasse#hausnummer#vorwahl#telnr
u.s.w.die erste Zeile kann ich einlesen, aber wie springe ich dann zur 2. Zeile?
-
wie du im CodeAusriss siehst ist da ein
while(fgets(buffer0,BUFFERLEN,ifp) { ... }
dies sorgt dafür das ganze file Zeile für Zeile gelesen und verarbeitet wird
Deine Demodatei sollte zumindest so aussehen
vname1#nname1#wohnort1#plz1#strasse1#hausnummer1#vorwahl1#telnr1 vname2#nname2#wohnort2#plz2#strasse2#hausnummer2#vorwahl2#telnr2 vname3#nname3#wohnort3#plz3#strasse3#hausnummer3#vorwahl3#telnr3 u.s.w.
Ich würde fürs debugging die Funktion ParseOneline wie folgt abändern
Damit du sehen kannst welche Zeile er gerade Beabeitetint ParseOneline(char *Buffer,PersSTRUCT *Data) { // Buffer vname#nname#wohnort#plz#strasse#hausnummer#vorwahl#telnr\r\n printf("\nDebugAusgabe gelesen:]%s[", Buffer) ....
Außerdem würde ich mir eine Funktion schreiben die den Inhalt der gesamten Liste auf dem Bildschirm ausgibt, damit
kann man überprüfen ob das Lesen korrekt erfolgt, wenn man sie vor das Ende der while Schleife in den Code einfügt.
-
Hi, irgendwie funktioniert es noch nicht.
So sieht es bei mir bis jetzt aus:datei = fopen("benutzer.txt","rb"); zeiger=anfang; while(fgets(buffer0,BUFFERLEN,datei)) { if(anfang == NULL) { anfang = (struct person*) malloc (sizeof(struct person)); ParseOneline(buffer0,data); anfang=data; anfang->next=NULL; } else { while(zeiger->next != NULL) zeiger=zeiger->next; zeiger->next= (struct person*) malloc (sizeof(struct person)); ParseOneline(buffer0,data); zeiger=data; zeiger->next=NULL; } } fclose(datei);
und
int ParseOneline(char *Buffer,struct person *data) { substr(Buffer,data->vname,'#'); substr(Buffer,data->nname,'#'); substr(Buffer,data->wohnort,'#'); substr(Buffer,data->plz,'#'); substr(Buffer,data->strasse,'#'); substr(Buffer,data->hausnummer,'#'); substr(Buffer,data->vorwahl,'#'); substr(Buffer,data->telnr,'#'); return 0; }
- anfang heißt bei mir das erste Listenelement
- zeiger die anderen
-
Das es nicht funktioniert ist schade.
Was funktioniert denn nicht, wenn ich diese Information hätte könnte ich vielleicht helfen.
- Comnpiler Fehler ?
- Runtime Fehler ?
- Falsche Daten ?Nicht böse sein, bin neugierig aber leider keine Hellseher
-
Ist ein Runtime-Fehler:
"Unbehandelte Ausnhame :System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
at substr(SByte* in, SByte* lowout, Sbyte search)
at ParseOnline(SByte* Buffer, person* data)
at main()"
-
Wenn ich das richtig interpretiere ist ein teil der Parameter von substr leer. das kann eigentlich nur buffer sein
Setz doch bitte vor jedes substr die folgende Zeile printf("Inhalt von Buffer ]%s[\n",buffer);
Damit wir sehen wie der gelesene Buffer aussieht vor während und nach dem zerlegen aussiehtint ParseOneline(char *Buffer,struct person *data) { printf("Inhalt von Buffer ]%s[\n",buffer); substr(Buffer,data->vname,'#'); printf("Inhalt von Buffer ]%s[\n",buffer); substr(Buffer,data->nname,'#'); printf("Inhalt von Buffer ]%s[\n",buffer); substr(Buffer,data->wohnort,'#'); printf("Inhalt von Buffer ]%s[\n",buffer); substr(Buffer,data->plz,'#'); printf("Inhalt von Buffer ]%s[\n",buffer); substr(Buffer,data->strasse,'#'); printf("Inhalt von Buffer ]%s[\n",buffer); substr(Buffer,data->hausnummer,'#'); printf("Inhalt von Buffer ]%s[\n",buffer); substr(Buffer,data->vorwahl,'#'); printf("Inhalt von Buffer ]%s[\n",buffer); substr(Buffer,data->telnr,'#'); printf("Inhalt von Buffer ]%s[\n",buffer); return 0; }
-
wo kommt bei die in dem Stück data her, ich glaube mein erster Verdacht war falsch, dein Data zeigt wahrscheinlich auf NULL
while(zeiger->next != NULL) //<=== Wofür das while?? du hängst beginnend vom ersten element ein Element zeiger=zeiger->next;// nach dem anderen an somit zeigt zeiger->next auf NULL zeiger->next= (struct person*) malloc (sizeof(struct person)); // ein malloc ohne Fehlerhandling Fast eine Todsünde ParseOneline(buffer0,data); //<========== hier müste zeiger stehen zeiger=data; zeiger->next=NULL; }
-
Also, wird einmal der Inhalt von "Buffer" ausgegeben und dann bricht das Programm mit einem Fehler ab.
Wenn ich noch vor das 1. printf
data = (struct person*) malloc (sizeof(struct person));
schreibe, werden 4 Zeilen ausgegeben und dann bricht das Programm ab!
-
wie sehen diese 4 Zeilen vom Inhalt aus?
-
ja, das while am Anfang muss weg. Ich hab ein bisschen Quellcode von einer Funktion kopiert, die ich auch mit eingearbeitet habe. Ist mit "reingerutscht"
zu dem Fehlerabfang - stimmt, wirklich ziemlich leichtsinnig!
-
funktionierts denn jetzt???
-
PAD schrieb:
funktionierts denn jetzt???
Nö!
PAD schrieb:
wie sehen diese 4 Zeilen vom Inhalt aus?
Auf dem Bildschirm wird folgendes ausgegeben:
Inhalt von Buffer ]vname1#nname1#wohnort1#plz1#strasse1#hausnummer1#vorwahl1#telnr1[
Inhalt von Buffer ]nname1#wohnort1#plz1#strasse1#hausnummer1#vorwahl1#telnr1[
Inhalt von Buffer ]wohnort1#plz1#strasse1#hausnummer1#vorwahl1#telnr1[
Inhalt von Buffer ]plz1#strasse1#hausnummer1#vorwahl1#telnr1[Danach kommt wieder die gleiche Fehlermeldung von vorhin!
-
ist data-plz ein string oder eine Integer????