einfach verkettete Liste



  • 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.


Anmelden zum Antworten