einfach verkettete Liste
-
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.
-
getch() ist kein C Standard.
getch() ist plattform- und compilerspezifisch.
Frage im richtigen Forum (nicht diesem) danach.
-
Danke für den Tipp! Aber eigentlich hab ich gar nicht nach getch gefragt!
-
Du musst in deiner liste auch weiterlaufen. name = name->next;
Was ist wenn du den ersten Eintrag der Liste löschen musst?
Was ist wenn es keinen Nachfolger gibt?Und ein paar printf() dazwischen helfen auch wenn du keinen Debugger nutzen willst. Mit "%p" kannst du auch Pointer ausgeben
printf("Name: %p ->next: %p\n", name, name->next);
-
So jetzt hier mal das komplette Programm:
#include<stdio.h> #include<stdlib.h> struct liste{ char nname[32]; char vname[32]; long nummer; struct liste *next;}; int zaehlen(struct liste *name){ char anfangsbuchstabe; int anzahl[26]; int i; for(i=0;i<26;i++) anzahl[i]=0; while(name!=NULL) {anfangsbuchstabe=name->nname[0]; anzahl[anfangsbuchstabe-'A']++; name=name->next; } for(i=0;i<26;i++) printf("%c: %d\n",i+'A', anzahl[i]); } int loeschen(struct liste *name){ int eingabe; struct liste *hilfszeiger; printf("Bitte geben Sie den Anfangsbuchstaben der zu loeschenden Namen ein: "); scanf("%c",&eingabe); while(name->next!=NULL) {hilfszeiger=name->next; if(name->nname[0]==eingabe) {name->next=hilfszeiger->next; free(hilfszeiger); break;} else name->next=hilfszeiger; name=name->next;} } int main(){ struct liste *anfang=NULL; struct liste *aktuell=NULL; struct liste *ausgabe; char text[100]; char wahl; FILE *datei; datei=fopen("D:\\liste.txt","r"); if(datei != NULL){ while(fgets(text,100,datei)){ if(anfang==NULL){ if((anfang = calloc(1,sizeof(struct liste)))==NULL) printf("FEHLER!!\n"); else{ sscanf(text,"%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; sscanf(text,"%s\t%s\t%ld\n",aktuell->nname,aktuell->vname,&aktuell->nummer); } }} else printf("Datei konnte nicht geoeffnet werden!\n"); fclose(datei); while(wahl !='q'){ printf("Was wollen Sie tun? Bitte druecken Sie q fuer Beenden, z fuer Zaehlen, l fuer Loeschen: "); scanf("%c",&wahl); switch (wahl){ case 'q': break; case 'l': loeschen(anfang); break; case 'z': zaehlen(anfang); break; } } system("Pause"); return 0; }
Warum werden die Elemente nicht gelöscht?
Warum wird die Fkt. löschen nicht aufgerufen wenn ich als wahl l eingebe?
-
Also eingeben kann ich jetzt schon mal was. Aber danach funktioniert nichts mehr.
Toll. Also war dein Versuch wohl nichts wert.
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.
...
Warum werden die Elemente nicht gelöscht?
Warum wird die Fkt. löschen nicht aufgerufen wenn ich als wahl l eingebe?Dein nächster Versuch war also auch nichts wert, da du offensichtlich nicht weißt, was getch() macht und was im Gegensatz dazu scanf("%c"...) macht, da helfen auch häßliche Formatierungen und das Weglassen von Informationen, was du denn nun zu deinem vorigen Versuch geändert hast, nichts.
Nicht viele Leute werden Lust haben, sich deinen häßlich formatierten Code ständig aufs Neue anzuschauen und die neu hinzugekommenen Fehler herauszusuchen um auch festzustellen, dass du schon mal angezeigte Fehler gar nicht bereinigt hast.