Verkettete Liste



  • In dem While Abbruchkriterium muss ein Fehler sein. Ich vrsuche schon die ganze Zeit zu Debuggen, aber dauernd stürzt der Editor ab. Vielleicht kann mir da jemand von euch weiterhelfen.

    int main(void){
    
    char c[30];
    int anzahl;
    anfang_ende_liste liste;
    char ende[]="ende";
    
    do{
    
        printf("Geben sie Land und Bevoelkerungsgroesse ein\n");
        scanf("%s %d",c,&anzahl);
    
        einfuegen(&liste,c,anzahl);
    
    }
    while(strcmp(ende,c) !=0);
    
    ausgeben(liste);
    
    return 0;
    }
    


  • Ich sehe keinen direkten Fehler (außer wenn Land > 30 Buchstaben), der zum Absturz führt. Vielleicht postest du mal den gesamten Code.

    ps: Bevor du einfügst prüf auch mal ob der Benutzer nicht ende eingegeben hat.



  • Um den Fehler zu finden habe ich mal das hier in der Uni versucht. Und die Ausgabe, die bei jeder Schleife erfolgt, ist eigentlich ok. Nur wenn man dann "ende" eingibt hängt er sich auf.

    int main(void){
    
      char c[30];
      int anzahl;
      anfang_ende_liste liste;
      char ende[]="ende";
    
      do{
    
        printf("Geben sie Land und Bevoelkerungsgroesse ein\n");
        scanf("%s %d",c,&anzahl);
    
        einfuegen(&liste,c,anzahl);
        ausgeben(liste);                    /*<----Test*/
    
      }
      while(strcmp(ende,c) !=0);
      ausgeben(liste);
    
      return 0;
    }
    

    Hier ist der gesamte (gute alte) code.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct Knot* Liste;
    
    typedef struct
        {
            char Name[30];
            int Einwohner; /*Einwohner in Millionen*/
    
        }Land;
    
    typedef struct Knot
        {
            Land eintrag;
            Liste vorgaenger;
            Liste nachfolger;
        }Knoten;
    
    typedef struct
        {
            Liste anfang;
            Liste ende;
        }anfang_ende_liste;
    
    void einfuegen(anfang_ende_liste* liste, char c, int anzahl){
    
        if(liste->anfang==NULL){
            Liste tmp=(Liste) malloc(1*sizeof(Knoten));
            liste->anfang=tmp;
            liste->ende=tmp;
            liste->anfang->nachfolger=NULL;
            liste->anfang->vorgaenger=NULL;
            strcpy(tmp->eintrag.Name, c);
            tmp->eintrag.Einwohner=anzahl;
        }
    
        if (anzahl<100){
            Liste tmp=(Liste) malloc(1*sizeof(Knoten));
            strcpy(tmp->eintrag.Name, c);
            tmp->eintrag.Einwohner=anzahl;
            tmp->vorgaenger=NULL;
            tmp->nachfolger=liste->anfang;
            liste->anfang=tmp;
            tmp->nachfolger->vorgaenger=tmp;
        }
    
        if (anzahl>=100){
            Liste tmp=(Liste) malloc(1*sizeof(Knoten));
            strcpy(tmp->eintrag.Name, c);
            tmp->eintrag.Einwohner=anzahl;
            tmp->nachfolger=NULL;
            tmp->vorgaenger=liste->ende;
            liste->ende=tmp;
            tmp->vorgaenger->nachfolger=tmp;
    
        }
    
    }
    
    void ausgeben(anfang_ende_liste liste){
        Liste tmp=liste.anfang;
        while (tmp!=0){
            printf("%s %d", tmp->eintrag.Name, tmp->eintrag.Einwohner);
            tmp=tmp->nachfolger;
    
        }
    }
    
    int main(void){
    
    char c[30];
    int anzahl;
    anfang_ende_liste liste;
    char ende[]="ende";
    
    do{
    
        printf("Geben sie Land und Bevoelkerungsgroesse ein\n");
        scanf("%s %d",c,&anzahl);
        einfuegen(&liste,c,anzahl);   
    
    }
    while(strcmp(ende,c) !=0);
    
    ausgeben(liste);
    
    return 0;
    }
    


  • Ich habe den Code jetzt auf einem anderen Rechner laufen lassen weil ich mir dachte, dass es vielleicht ein Problem ist, dass ich ein 64bit System habe (ganz naiv)

    Auf jeden Fall sehe ich jetzt mehr Fehlermeldungen.

    Bei den stringcopy aktionen läuft auch was schief.

    invalid conversion from car to const char*

    initializing argument 2 of char* strcpy(char*, const char*)

    mal sehen...



  • Den ersten Fehler findest du schon in den Übergabeparametern von einfuegen...



  • vielleicht habe ich da den stern vergessen

    einfuegen(&liste,*c,anzahl);



  • Jetzt werden auch auf meinem Laptop keine errors mehr angzeigt. und das Programm stürzt ab. Ok. Ich geb auf. Aber vielen Dank für Eure Hilfe. Ich hab trotzdem super viel dazu gelernt. Besonders durch die geposteten Beispiele.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct Knot* Liste;
    
    typedef struct
        {
            char Name[30];
            int Einwohner; /*Einwohner in Millionen*/
    
        }Land;
    
    typedef struct Knot
        {
            Land eintrag;
            Liste vorgaenger;
            Liste nachfolger;
        }Knoten;
    
    typedef struct
        {
            Liste anfang;
            Liste ende;
        }anfang_ende_liste;
    
    void einfuegen(anfang_ende_liste* liste, char c, int anzahl){
    
        if(liste->anfang==NULL){
            Liste tmp=(Liste) malloc(1*sizeof(Knoten));
            liste->anfang=tmp;
            liste->ende=tmp;
            liste->anfang->nachfolger=NULL;
            liste->anfang->vorgaenger=NULL;
            strcpy(tmp->eintrag.Name, &c);
            tmp->eintrag.Einwohner=anzahl;
        }
    
        if (anzahl<100){
            Liste tmp=(Liste) malloc(1*sizeof(Knoten));
            strcpy(tmp->eintrag.Name, &c);
            tmp->eintrag.Einwohner=anzahl;
            tmp->vorgaenger=NULL;
            tmp->nachfolger=liste->anfang;
            liste->anfang=tmp;
            tmp->nachfolger->vorgaenger=tmp;
        }
    
        if (anzahl>=100){
            Liste tmp=(Liste) malloc(1*sizeof(Knoten));
            strcpy(tmp->eintrag.Name, &c);
            tmp->eintrag.Einwohner=anzahl;
            tmp->nachfolger=NULL;
            tmp->vorgaenger=liste->ende;
            liste->ende=tmp;
            tmp->vorgaenger->nachfolger=tmp;
    
        }
    
    }
    
    void ausgeben(anfang_ende_liste liste){
    
        Liste tmp=liste.anfang;
        while (tmp!=0){
            printf("%s %d", tmp->eintrag.Name, tmp->eintrag.Einwohner);
            tmp=tmp->nachfolger;
    
        }
    }
    
    int main(void){
    
    char c[30];
    int anzahl;
    anfang_ende_liste liste;
    char ende[]="ende";
    
    do{
    
        printf("Geben sie Land und Bevoelkerungsgroesse ein\n");
        scanf("%s %d",c,&anzahl);
    
        einfuegen(&liste,*c,anzahl);
    
    }
    while(strcmp(ende,c) !=0);
    
    ausgeben(liste);
    
    return 0;
    }
    


  • Ich habe dir einige Fehler berichtigt, es können (und sind wahrscheinlich) noch genug Fehler für dich übrig.

    #include <stdio.h> 
    #include <stdlib.h> 
    #include <string.h> 
    
    typedef struct Knot* Liste; 
    
    typedef struct 
    { 
        char Name[30]; 
        int Einwohner;
    }Land; 
    
    typedef struct Knot 
    { 
        Land eintrag; 
        Liste vorgaenger; 
        Liste nachfolger; 
    }Knoten; 
    
    typedef struct 
    { 
        Liste anfang; 
        Liste ende; 
    }anfang_ende_liste; 
    
    void einfuegen(anfang_ende_liste* liste, char *c, int anzahl){ //muss char* sein da es sonst nur ein Zeichen ist
    
        if(liste->anfang==NULL){ 
            Liste tmp=(Liste) malloc(1*sizeof(Knoten)); 
            liste->anfang=tmp; 
            liste->ende=tmp; 
            liste->anfang->nachfolger=NULL; 
            liste->anfang->vorgaenger=NULL; 
            strcpy(tmp->eintrag.Name, c); //darf nicht die Adresse übergeben Pointer ist schon die Adresse
            tmp->eintrag.Einwohner=anzahl; 
        } 
        else if (anzahl<100){ //else if sonst wird ein element mehrfach erzeugt
            Liste tmp=(Liste) malloc(1*sizeof(Knoten)); 
            strcpy(tmp->eintrag.Name, c); //darf nicht die Adresse übergeben Pointer ist schon die Adresse
            tmp->eintrag.Einwohner=anzahl; 
            tmp->vorgaenger=NULL; 
            tmp->nachfolger=liste->anfang; 
            liste->anfang=tmp; 
            tmp->nachfolger->vorgaenger=tmp; 
        } 
    	else{ //else nicht immer if
            Liste tmp=(Liste) malloc(1*sizeof(Knoten)); 
            strcpy(tmp->eintrag.Name, c); //darf nicht die Adresse übergeben Pointer ist schon die Adresse
            tmp->eintrag.Einwohner=anzahl; 
            tmp->nachfolger=NULL; 
            tmp->vorgaenger=liste->ende; 
            liste->ende=tmp; 
            tmp->vorgaenger->nachfolger=tmp; 
    
        } 
    } 
    
    void ausgeben(anfang_ende_liste *liste){ //Übergabe des pointers keine kopie
        Liste tmp=liste->anfang; //Operator ersetzt wegen pointer
        while (tmp){ 
            printf("%s %d", tmp->eintrag.Name, tmp->eintrag.Einwohner); 
            tmp=tmp->nachfolger; 
        } 
    } 
    
    int main(){ 
    	char c[30]; 
    	int anzahl; 
    	anfang_ende_liste liste = {0}; //Strukt mit 0 initialisieren, sonst scheitert die Prüfung der Zeiger auf NULL mit Programmabsturz
    	char ende[]="ende"; 
    
    	do{ 
    		printf("Geben sie Land und Bevoelkerungsgroesse ein\n"); 
    
    		if(2 == scanf("%s%d",c,&anzahl)) //Prüfe zusätzlich ob auch 2 Eingaben gemacht wurden
    			einfuegen(&liste,c,anzahl); 
    	} while(strcmp(ende,c) !=0); 
    
    	ausgeben(&liste); //adresse wegen pointer
    
    	return 0; 
    }
    


  • Vielen Dank für die Antwort. Mir ist aber einfach folgendes nicht klar:

    In der uni habe ich ja diesen Test gemacht:

    int main(void){
    
      char c[30];
      int anzahl;
      anfang_ende_liste liste;
      char ende[]="ende";
    
      do{
    
        printf("Geben sie Land und Bevoelkerungsgroesse ein\n");
        scanf("%s %d",c,&anzahl);
    
        einfuegen(&liste,c,anzahl);
        ausgeben(liste);                    /*<----Test*/
    
      }
      while(strcmp(ende,c) !=0);
      ausgeben(liste);
    
      return 0;
    }
    

    Mit meiner alten Version des Programms. Dann kam die Eingabeaufforderung "Geben sie Land.............". Wenn ich dann "Deutschland 80" eingegeben habe kamm die Ausgabe deutschland100. Dann kam wieder die Aufforderung und ich habe eigegeben "Italien 70" und es kam raus: italien70 deutschland 80. Es hat als wirklich geklappt. Das kann docj eigentlich nicht sein, oder?



  • Kann schon sein, wenn der Compiler in der Uni die Strukt automatisch auf 0 gesetzt hat und deiner daheim nicht(was korrekt ist). Da die Strukt nicht 0 ist kann dort jeder Wert stehen und somit schlug deine Prüfung fehl.



  • noch eine frage: greift das abbruchkriterium nicht doch falsch? scanf erwartet doch einen string und eine zahl. außerdem wird doch ende noch in die liste eingefügt, weil er mit do dirket in die schleife reingeht und der abbruch erst am ende erfolgt



  • Da fehlt halt noch mindestens eine Überprüfung damit ende nicht eingefügt wird. Es gibt immer etwas zu verbessern und ich habe gerade nur das Nötigste verbessert.



  • ... das ist wirklich so. wenn ich ende 0 eingebe, dann klappt es. das wird dann aber auch noch in die liste eingetragen.

    Aber das kann man ja leicht ändern.

    Nochmals vielen vielen Dank! Endlich klappts



  • Ich sage ja auch, dass ich dir super dankbar bin. Ohne Dich hätte ich das nie auf die Reihe bekommen


Anmelden zum Antworten