tutorials.de Buch-Aktion 05/2012
ERLEDIGT
JA
ANTWORTEN
10
ZUGRIFFE
164
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    yax yax ist offline Mitglied Gold
    Registriert seit
    Jul 2010
    Beiträge
    175
    Hey,
    also ich wusste garnicht wirklich wie ich dieses Thema hier nennen soll, denn ich weiß nicht wirklich was ich falsch gemacht habe...

    Ich lese schon seit längeren ein Buch über C und nun bin ich bei den verketteten Listen. Ich habe ein Programm geschrieben das mit einer verketteten Liste Abreitet. Jetzt habe ich aber ein Problem, welches miener Meinung garnichts damit zu tun hat. Wenn ich bei meinem Programm ein neues Element in der Liste erstellen wird, funktioniert die Eingabe nicht wirklich. Ich kann nämlich keinen Namen eingeben, es wird übersprungen.

    Kann mir jemand helfen?

    Code:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define BUF 255
     
    struct Noten {
           char name[BUF];
           int note;
           struct Noten *next;
    };
     
    struct Noten *anfang = NULL;
     
    void hinzufuegen(char *name, int note) {
         struct Noten *zeiger;
         
         if(anfang == NULL) {
           if((anfang = malloc(sizeof(struct Noten))) == NULL) {
             fprintf(stderr, "Konnte keinen Speicher anfordern\n");
             return;
           }
           strcpy(anfang->name, name);
           anfang->note = note;
           anfang->next = NULL;
         } else {
           zeiger = anfang;
           
           while(zeiger->next != NULL)
             zeiger = zeiger->next;
           
           if((zeiger->next=malloc(sizeof(struct Noten))) == NULL) {
             fprintf(stderr, "Konnte keinen Speicher anfordern\n");
             return;
           }
           zeiger = zeiger->next;
           strcpy(zeiger->name, name);
           zeiger->note = note;
           zeiger->next = NULL;
         }
    }
     
    void eingabe(void) {
         char name[BUF];
         int note;
         
         printf("Name....: ");
         fgets(name, BUF, stdin);
         printf("Note....: ");
         scanf("%d", &note);
         hinzufuegen(name, note);
    }
     
    void loesche(char *name) {
         struct Noten *weg, *vor;
         
         if(anfang != NULL) {
           if(strcmp(anfang->name, name) == 0) {
             weg = anfang->next;
             free(anfang);
             anfang = weg;
           }else {
             vor = anfang; //vor wird auf den Anfang gesetzt
             
             while(vor->next != NULL) {  //Gibt es ein nächstes Element in der Liste?
               weg = vor->next;          //Wenn Ja, dann gebe weg, die Adresse des nächsten Elementes. Beim ersten durchlauf ist vor = Anfang. Da aber anfang nicht das gesuchte Element sein kann, kann das nächste element das mögliche sein, dass gelöscht werden soll
               if(strcmp(weg->name, name) == 0) {  //Ist das Element (Im ersten durchlauf das Element nach Anfang) das gesuchte,
                 vor = weg->next;         //dann bekommt das Element davor die Adresse des Elements des nächsten, als Parameter für *next, da es nach dem löschen des einen, das nächste Element wäre (Im 1. Durchlauf das 3. Element), somit steht das ELement das gelöscht werden kann "frei"
                 free(weg);               //Somit wird es jetzt auch "freigelassen"
                 break;                   //Und es wird aus der while()-Schleife gesprungen, da das gesuchte Element gefunden und gelöscht wurde
               }
             }
           }
         }else
           printf("Es konnte kein Element gefunden wurden\n");
    }
     
    void ausgabe(void) {
         struct Noten *zeiger = anfang;
         
         printf("\n\n");
         printf("==============================\n");
         printf("          Name      |   Note  \n");
         printf("==============================\n");
         
         if(anfang != NULL) {
           while(zeiger != NULL) {
             printf("|         %s        |    %d  |\n", zeiger->name, zeiger->note);
             zeiger = zeiger->next;
           }
           printf("\n\n");
         } else
           printf("Es sind keine Daten in der Liste vorhanden!\n\n");
    }
     
    int main(void) {
        int auswahl;
        char name[BUF];
        
        do {
          printf("Was wollen sie machen\n\n");
          printf("-1- Einen neuen Eintrag machen\n");
          printf("-2- Alle Eintraege ausgeben\n");
          printf("-3- Ein Element loeschen\n");
          printf("-0- Programm beenden\n");
          printf("Ihre Auswahl: ");
          scanf("%d", &auswahl);
          
          switch(auswahl) {
            case 1: eingabe();     break;
            case 2: ausgabe();     break;
            case 3: printf("Wie lautet der Name der geloescht werden soll: ");
                    fgets(name, BUF, stdin);
                    loesche(name);
                    break;
            case 0: break;
            default: printf("Falsche Eingabe!!\n");
          }
        }while(auswahl != 0);
        
        system("PAUSE");
        return EXIT_SUCCESS;
    }
     

  2. #2
    Avatar von sheel
    sheel sheel ist offline Moderator
    tutorials.de Moderator
    Registriert seit
    Jul 2007
    Beiträge
    4.501
    Hi

    scanf und gets (und Abartender beiden) haben leider manchmal ein Problem damit, im gleichen Programm verwendet zu werden.

    Ich hab eine Einlesefunktion, die das (und auch ein weiteres Problem bei fgets) umgeht,
    muss sie nur kurz suchen...

    edit:
    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    int readline(char *buffer, int maxlen)
    {
        int i;
        if(NULL == fgets(buffer, maxlen, stdin))
            return 1;
        i = strlen(buffer) - 1;
        if(i >= 0 && buffer[i] == '\n')
            buffer[i] = '\0';
        else
        {
            while(fgetc(stdin) != '\n');
        }
        return 0;
    }

    Verwendung für Strings sollte klar sein: Als Parameter den String und die maximale Länge.
    Wenn der Returnwert 0 ist: Alles gut. Sonst 1.

    Für ein int zuerst als String einlesen und dann zB. mit sscanf herauslesen
    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    char x[1234];
    int i;
    ...
    if(readline(x, 1234))
    {
        //Fehler
    }
    if(1 != sscanf(x, "%d", &i))
    {
        //Fehler
    }

    Gruß
    Geändert von sheel (15.08.11 um 18:52 Uhr)
     

  3. #3
    yax yax ist offline Mitglied Gold
    Registriert seit
    Jul 2010
    Beiträge
    175
    Aber ich benutze doch nur fgets, also nichts anderes in diesem Programm
     

  4. #4
    Avatar von sheel
    sheel sheel ist offline Moderator
    tutorials.de Moderator
    Registriert seit
    Jul 2007
    Beiträge
    4.501
    Dann schau doch mal genau...ich finde mehrere scanf
     

  5. #5
    yax yax ist offline Mitglied Gold
    Registriert seit
    Jul 2010
    Beiträge
    175
    Okay, ich hab auch noch scanf() im Programm, stimmt

    Ich habe deine Funktion ausprobiert, aber die Eingabe für Name wird immer noch übersprungen...
     

  6. #6
    Avatar von sheel
    sheel sheel ist offline Moderator
    tutorials.de Moderator
    Registriert seit
    Jul 2007
    Beiträge
    4.501
    Wo denn ausprobiert?
    Solange scanf drin bleibt, hat das wenig Sinn.
     

  7. #7
    yax yax ist offline Mitglied Gold
    Registriert seit
    Jul 2010
    Beiträge
    175
    Ich habe ja alle scanf und fgets funktionen durch deine Funktion ersetzt, und ich habe immer noch das gleiche Problem
     

  8. #8
    Avatar von sheel
    sheel sheel ist offline Moderator
    tutorials.de Moderator
    Registriert seit
    Jul 2007
    Beiträge
    4.501
    Ich werds bei mir einmal kompilieren...

    also ich kann einfügen, löschen, ausgeben und beenden ohne Probleme.

    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define BUF 255
     
    int readline(char *buffer, int maxlen)
    {
        int i;
        if(NULL == fgets(buffer, maxlen, stdin))
            return 1;
        i = strlen(buffer) - 1;
        if(i >= 0 && buffer[i] == '\n')
            buffer[i] = '\0';
        else
        {
            while(fgetc(stdin) != '\n');
        }
        return 0;
    }
     
    struct Noten {
           char name[BUF];
           int note;
           struct Noten *next;
    };
     
    struct Noten *anfang = NULL;
     
    void hinzufuegen(char *name, int note) {
         struct Noten *zeiger;
         
         if(anfang == NULL) {
           if((anfang = (struct Noten *)malloc(sizeof(struct Noten))) == NULL) {
             fprintf(stderr, "Konnte keinen Speicher anfordern\n");
             return;
           }
           strcpy(anfang->name, name);
           anfang->note = note;
           anfang->next = NULL;
         } else {
           zeiger = anfang;
           
           while(zeiger->next != NULL)
             zeiger = zeiger->next;
           
           if((zeiger->next=(struct Noten *)malloc(sizeof(struct Noten))) == NULL) {
             fprintf(stderr, "Konnte keinen Speicher anfordern\n");
             return;
           }
           zeiger = zeiger->next;
           strcpy(zeiger->name, name);
           zeiger->note = note;
           zeiger->next = NULL;
         }
    }
     
    void eingabe(void) {
         char name[BUF];
         char not[BUF];
         int note;
         
         printf("Name....: ");
         readline(name, BUF);
         printf("Note....: ");
         readline(not, BUF);
         sscanf(not,"%d",&note);
         hinzufuegen(name, note);
    }
     
    void loesche(char *name) {
         struct Noten *weg, *vor;
         
         if(anfang != NULL) {
           if(strcmp(anfang->name, name) == 0) {
             weg = anfang->next;
             free(anfang);
             anfang = weg;
           }else {
             vor = anfang; //vor wird auf den Anfang gesetzt
             
             while(vor->next != NULL) {  //Gibt es ein nächstes Element in der Liste?
               weg = vor->next;          //Wenn Ja, dann gebe weg, die Adresse des nächsten Elementes. Beim ersten durchlauf ist vor = Anfang. Da aber anfang nicht das gesuchte Element sein kann, kann das nächste element das mögliche sein, dass gelöscht werden soll
               if(strcmp(weg->name, name) == 0) {  //Ist das Element (Im ersten durchlauf das Element nach Anfang) das gesuchte,
                 vor = weg->next;         //dann bekommt das Element davor die Adresse des Elements des nächsten, als Parameter für *next, da es nach dem löschen des einen, das nächste Element wäre (Im 1. Durchlauf das 3. Element), somit steht das ELement das gelöscht werden kann "frei"
                 free(weg);               //Somit wird es jetzt auch "freigelassen"
                 break;                   //Und es wird aus der while()-Schleife gesprungen, da das gesuchte Element gefunden und gelöscht wurde
               }
             }
           }
         }else
           printf("Es konnte kein Element gefunden wurden\n");
    }
     
    void ausgabe(void) {
         struct Noten *zeiger = anfang;
         
         printf("\n\n");
         printf("==============================\n");
         printf("          Name      |   Note  \n");
         printf("==============================\n");
         
         if(anfang != NULL) {
           while(zeiger != NULL) {
             printf("|         %s        |    %d  |\n", zeiger->name, zeiger->note);
             zeiger = zeiger->next;
           }
           printf("\n\n");
         } else
           printf("Es sind keine Daten in der Liste vorhanden!\n\n");
    }
     
    int main(void) {
        int auswahl;
        char name[BUF];
        
        do {
          printf("Was wollen sie machen\n\n");
          printf("-1- Einen neuen Eintrag machen\n");
          printf("-2- Alle Eintraege ausgeben\n");
          printf("-3- Ein Element loeschen\n");
          printf("-0- Programm beenden\n");
          printf("Ihre Auswahl: ");
          readline(name, BUF);
         sscanf(name,"%d",&auswahl);
          
          switch(auswahl) {
            case 1: eingabe();     break;
            case 2: ausgabe();     break;
            case 3: printf("Wie lautet der Name der geloescht werden soll: ");
                    readline(name, BUF);
                    loesche(name);
                    break;
            case 0: break;
            default: printf("Falsche Eingabe!!\n");
          }
        }while(auswahl != 0);
        
        system("PAUSE");
        return EXIT_SUCCESS;
    }

    Gruß
    Geändert von sheel (15.08.11 um 19:20 Uhr)
     

  9. #9
    yax yax ist offline Mitglied Gold
    Registriert seit
    Jul 2010
    Beiträge
    175
    Okay!? Also ich weiß jetzt nicht wirklich wieseo, aber es funktioniert jetzt auch.. Ich gehe mal beide Dateien durch, und gucke was ich bei meiner Falsch gemacht habe

    Vielen Dank sheel

    Edit: Ich hab's. Ich habe ein scanf übersehen
    Geändert von yax (15.08.11 um 19:27 Uhr)
     

  10. #10
    yax yax ist offline Mitglied Gold
    Registriert seit
    Jul 2010
    Beiträge
    175
    @sheel: ich hab mir eben nochmal die funktion angeschaut. Ich verstehe das was unter else steht nicht. Müsste das nicht so lauten****
    Code :
    1
    2
    3
    
    else {
      while((i=fgetc(stdin)) != '\n');
    }

    Falls ich jetzt etwas Falsches gesagt habe, korrigiere mich bitte
     

  11. #11
    Avatar von sheel
    sheel sheel ist offline Moderator
    tutorials.de Moderator
    Registriert seit
    Jul 2007
    Beiträge
    4.501
    Ist weder besser noch schlechter.
    Unnötig, sollte aber trotzdem funktionieren.

    Wenn du es genauer verstehen willst:
    Ich hab mal eine Erklärung zu der Funktion geschrieben.
    Ist über mehrere Beiträge verteilt, auch auf der zweiten Seite.
    http://www.tutorials.de/c-c/373160-p...t-getchar.html
    Achtung, lang!

    Gruß
     

Ähnliche Themen

  1. Komisches DIV-Problem
    Von crashx im Forum CSS
    Antworten: 7
    Letzter Beitrag: 01.08.10, 12:47
  2. komisches Problem?!
    Von CarnivoreCI im Forum CSS
    Antworten: 3
    Letzter Beitrag: 16.07.06, 09:59
  3. Komisches Problem
    Von marian im Forum Flash Plattform
    Antworten: 4
    Letzter Beitrag: 04.01.05, 19:14
  4. Komisches Problem?
    Von Paranoid im Forum HTML & XHTML
    Antworten: 6
    Letzter Beitrag: 09.08.02, 20:45
  5. Komisches Problem
    Von Interritor im Forum CGI, Perl, Python, Ruby, Power Shell
    Antworten: 0
    Letzter Beitrag: 27.06.01, 12:26