einfach verkettete Liste
-
Hallo,
ich habe eine Datei in der Nachname, Vorname, Personalnummer steht und diese Daten sollen ausgelesen werden und in einer Liste abgelegt werden.
#include<stdio.h> #include<stdlib.h> struct liste{ char nname[32]; char vname[32]; long nummer; struct liste *next;}; int main(){ struct liste *anfang=NULL; struct liste *aktuell=NULL; struct liste *ausgabe; FILE *datei; datei=fopen("liste.txt","r"); if(datei != NULL){ if(anfang==NULL){ if((anfang = calloc(1,sizeof(struct telefon)))==NULL) printf("FEHLER!!\n"); else{ fscanf(datei,"%s\t%s\t%ld\n",anfang->nname,anfang->vname,&anfang->nummer); anfang->next=NULL;} } aktuell = anfang; while(aktuell ->next !=NULL) aktuell = aktuell -> next; if((aktuell -> next=calloc(1,sizeof(struct telefon)))==NULL) printf("FEHLER!!\n"); else{ aktuell = aktuell -> next; fscanf(datei,"%s\t%s\t%ld\n",aktuell->nname,aktuell->vname,&aktuell->nummer); } } else printf("Datei konnte nicht geoeffnet werden!\n"); ausgabe=anfang; while(ausgabe!=NULL){ printf("%s\t%s\t%ld\n",ausgabe->nname,ausgabe->vname,ausgabe->nummer); ausgabe=ausgabe->next; } return 0; }
Klappt auch soweit, bis auf die Tatsache, dass ich nur die ersten zwei Datensätze ausgegeben bekomme. Ist bei dem einlesen oder bei der Ausgabe was falsch?
-
Wo (in dem geposteten Code) soll denn ein evtl. vorhandener dritter Datensatz eingelesen werden?
-
Du verwendest das für Anfänger äußerst unpraktikable fscanf statt fgets/sscanf und fragst noch nicht mal den Rückgabewert ab. So kann das nichts werden.
-
Es wird aber doch was für die ersten zwei Datensätze!
Wenn ich Belli richtig verstehe muss ich noch eine Schleife einbauen, da ich nicht weiß wieviele Datensätze in der Datei sind (weit über 100).
-
Also habe es jetzt so versucht:
if(datei != NULL){ if(anfang==NULL){ if((anfang = calloc(1,sizeof(struct liste)))==NULL) printf("FEHLER!!\n"); else{ fscanf(datei,"%s\t%s\t%ld\n",anfang->nname,anfang->vname,&anfang->nummer); anfang->next=NULL;} } aktuell = anfang; while(aktuell ->next !=NULL) aktuell = aktuell -> next; if((aktuell -> next=calloc(1,sizeof(struct liste)))==NULL) printf("FEHLER!!\n"); else{ aktuell = aktuell -> next; while(fscanf(datei,"%s\t%s\t%ld\n",aktuell->nname,aktuell->vname,&aktuell->nummer)!=EOF)
Dann bekomme ich das erste und das letzte Element ausgegeben.
-
großer schrieb:
...
Wenn ich Belli richtig verstehe muss ich noch eine Schleife einbauen, da ich nicht weiß wieviele Datensätze in der Datei sind (weit über 100).Der Trick heißt EOF (End Of File).
Gibt es als Rückgabewert von den meisten f....() Funktionen oder als Funktion feof().
-
Der Trick heißt EOF (End Of File).
Gibt es als Rückgabewert von den meisten f....() Funktionen oder als Funktion feof().Ja hab ich ja gemacht! Wie bekomm ich jetzt das zweite bis vorletzte Element noch in meine Liste?
-
Nein, nicht um das scanf.
Um das ganze Zeug nach if(datei != NULL)if(datei != NULL){ while (fgets(text,datei)!=EOF) // über den Syntax von fgets musst du dich schlau machen { .... if(anfang==NULL){ .... ... sscanf(text,"%s\t%s\t%ld\n",anfang->nname,anfang->vname,&anfang->nummer); .... } else { ..... sscanf(text,"%s\t%s\t%ld\n",anfang->nname,anfang->vname,&anfang->nummer); .... ... } fclose(datei); }
-
Danke! So funktioniert es. Wie kann ich jetzt mittels einer Funktion die Anfangsbuchstaben der Nachnamen zählen?
Habe ma so angefangen, aber das wird wohl nichts.int zaehlen(struct liste *name){ char c; while(c=getc(name->nname)!=EOF)
Mit dem getc würde ich ja alle Buchstaben des Nachnamen auslesen??
-
Wie kommst Du denn auf die Funktion getc?
Was denkst Du, bewirkt die Funktion getc?
-
getc liest ein Zeichen aus einer Datei oder auch stdin.
Du willst das aber von Strings wissen, die ja schon im Speicher liegen.Mit name->nname[0] bekommst du den ersten Buchstaben.
Ich gehe mal davon aus, dass du wissen möchtest, wieviel Nachnamen mit 'A' oder 'B' ...'Z' anfangen.
Dann brauchst du noch ein Feld z.B anzahl[26]
char Anfangsbuchstabe; char anzahl[26]; // anzahl['Z'-'A'+1]; Solange ein Nachname da ist: Anfangsbuchstabe = name->nname[0]; // noch Testen ob Anfangsbuchstabe groß und im Bereich A-Z ist. anzahl[Anfangsbuchstabe-'A']++; Nächster Nachname
-
Hab es probiert funktioniert aber so nicht. Was ist denn daran falsch?
while(name!=NULL) {anfangsbuchstabe=name->nname[0]; anzahl[anfangsbuchstabe-'A']++; }
-
großer schrieb:
Hab es probiert funktioniert aber so nicht. Was ist denn daran falsch?
Was funktioniert nicht?
Was passiert?
Was erwartest du?while(name!=NULL) {anfangsbuchstabe=name->nname[0]; anzahl[anfangsbuchstabe-'A']++; printf("Nachname: <%s> Anfangsbuchstabe: <%c> Index: %d\n", name->nname, anfangsbuchstabe, anfangsbuchstabe-'A'); }
-
Na ich möchte nach der Schleife alle Buchstaben stehen haben und wie oft diese vorkommen. Hab ich versucht wird aber nichts ausgegeben. Wenn ich das so mache wie du es gerade geschriben hast bekomm ich immer nur das erste Element in einer Endlosschleife?
-
großer schrieb:
... bekomm ich immer nur das erste Element in einer Endlosschleife?
Das habe ich mir gedacht.
Und was schließt du daraus?
-
Das schließ ich daraus!
while(name!=NULL) {anfangsbuchstabe=name->nname[0]; anzahl[anfangsbuchstabe-'A']++; name=name->next; } for(i=0;i<26;i++) printf("%d\n",anzahl[i]); }
So bekomm ich aber utopische Werte für die Anzahl. Wie bekomm ich jetzt noch die entsprechenden Buchstaben für die Anzahl davor?
-
Fein.
Mach mal
for(i=0;i<26;i++) printf("%c: %d\n",i+'A', anzahl[i]);
vor deiner Zählung.
-
Supi! Passt jetzt! Aber es geht ja noch weiter
Und zwar soll jetzt ein Buchstabe eingelesen werden und alle Elemente der Liste dessen Nachname mit dem Buchstaben anfangensollen gelöscht werden. Folgendes hab ich versucht:int loeschen(struct liste *name){ int eingabe; struct liste *hilfszeiger; printf("Bitte geben Sie den Anfangsbuchstaben der zu loeschenden Namen ein: "); eingabe=getch(); while(name->next!=NULL) {hilfszeiger=name->next; if(name->nname[0]==eingabe) {name->next=hilfszeiger->next; free(hilfszeiger); break;} else name->next=hilfszeiger;} }
Allerdings scheitert es schon beim eingeben des Buchstaben. Das printf erscheint zwar aber ich kann nichts eingeben??
-
Bei Eingaben von stdin halte ich mich mal zurück. Mache ich zu selten.
Aber probier doch mal scanf("%c ", &eingabe);Du solltest auch deine Listenverwaltung in eigene Funktionen auslagern.
Also Funktionen zum Einfügen, Löschen, Suchen von Einträgen.Und Eingaben haben in solchen Funktionen nichts zu suchen
-
Also eingeben kann ich jetzt schon mal was. Aber danach funktioniert nichts mehr. Hab das zaehlen jetzt nach den loeschen gemacht und das wird nicht mehr ausgeführt! Würde es gerne so machen das nur der Buchstabe eingegeben werden muss ohne das die Entertaste gedrückt werden muss, deshalb hab ich auch das getch genommen.