übung listen



  • int main(void)
    

    und der main block muss nicht mit einem ; abgeschlossen werden....



  • Moinsen

    Also wie gesagt, der main-Funktion muss ein int oder zumindest void vorgestellt werden 😉 Außerdem gilt folgendes

    scanf("%s",&alter[i]);
    

    statt

    scanf("%s",alter[i]);
    

    da scanf eine Adresse erwartet.

    Und

    aktuell= (struct daten*) malloc(sizeof(struct daten));
    

    statt

    aktuell= malloc(sizeof(struct daten));
    

    da malloc dir sonst nur void-Pointer bastelt.

    So läßt sich das ganze zumindest übersetzen, "laufen" tut es trotzdem so nicht.



  • ich habe jetzt alles geändert und es hat sich eine veränderung eingestellt.
    das programm stürzt nicht ab, sondern es zeigt nichts an- ich weiß zwar nicht ob das besser ist, weil kommt ja nsicht raus, aber nicht anzeigen ist besser als nichts!

    jemand noch eine idee? 😕



  • stoeoe schrieb:

    ich habe jetzt alles geändert und es hat sich eine veränderung eingestellt.
    das programm stürzt nicht ab, sondern es zeigt nichts an- ich weiß zwar nicht ob das besser ist, weil kommt ja nsicht raus, aber nicht anzeigen ist besser als nichts!

    jemand noch eine idee? 😕

    Naja, wenn ich mir deinen Code so angucken, dann sieht das sehr stark danach aus, als hättest du dir zwischen Zeile 20 und 45 mehrfach Endlosschleifen gebastelt. Alleine folgender Code enthält schon einige Stolpersteine (finde ich zumindest)

    for (i=0;i<20;i++)
    {
        name[i]='\0';
        i=0;
        do
        {
            scanf("%s",name[i]);
            i++;
        }
        while (name[i-1]!=32);
    }
    

    1. Du hast "name[10]" definiert, läßt den Laufindex i aber bis vor 20 laufen.

    2. Hat es einen tieferen Sinn, dass du beim Eintritt in die For-Schleife, bei dem i ja noch den Wert null hat, das i-te Elemten von "name[]", also das null-te Element, mit "\0" terminieren willst?

    3. i = 0 macht dem zufolge auch erst am Ende des For-Blocks Sinn, da i vor der do-while-Schleife eh noch null ist.

    4. Mit "scanf("%s",name[i]);" bei i == 0 überschreibst du deine vorherige Terminierung ja eh wieder 😉

    5. Mit i++ bastelst du dir in der do-while-Schleife eine Endlosschleife, weil du keine vernünftige Abbruchbedinung eingebaut hast. Mal davon abgesehen, dass deine Abbruchbedingung über die Indizierung deines Arrays "name[]" nicht sehr geschickt ist. Denn was passiert, wenn 1. name[i] > als name[0] bis name[9] wird, 2. damit dann über deinen vordefinierten Speicher hinaus schreibst und 3. innerhalb deines gültigen Bereichs nie die Leertaste gedrückt wird? 😉



  • Berufspenner schrieb:

    Und

    aktuell= (struct daten*) malloc(sizeof(struct daten));
    

    statt

    aktuell= malloc(sizeof(struct daten));
    

    da malloc dir sonst nur void-Pointer bastelt.

    du kannst aber den rückgabewert von malloc (void*) einem anderen pointer ohne cast zuweisen. das ist kein problem.
    🙂



  • fricky schrieb:

    Berufspenner schrieb:

    Und

    aktuell= (struct daten*) malloc(sizeof(struct daten));
    

    statt

    aktuell= malloc(sizeof(struct daten));
    

    da malloc dir sonst nur void-Pointer bastelt.

    du kannst aber den rückgabewert von malloc (void*) einem anderen pointer ohne cast zuweisen. das ist kein problem.
    🙂

    Solange der Code auch wirklich mit einem C-Compiler und nicht mit einem C++-Compiler übersetzt wird. Oder was meinst du damit genau?



  • Berufspenner schrieb:

    Solange der Code auch wirklich mit einem C-Compiler und nicht mit einem C++-Compiler übersetzt wird. Oder was meinst du damit genau?

    ich meine damit, dass er den cast weglassen kann, ja sogar besser weglassen sollte.
    🙂



  • fricky schrieb:

    Berufspenner schrieb:

    Solange der Code auch wirklich mit einem C-Compiler und nicht mit einem C++-Compiler übersetzt wird. Oder was meinst du damit genau?

    ich meine damit, dass er den cast weglassen kann, ja sogar besser weglassen sollte.
    🙂

    Wieso "weglassen sollte" (persönliche Neugierde 😉 )? Und ein C++-Compiler haut ihm wie gesagt eins um die Ohre, wenn er das ganze nicht castet 😉



  • Berufspenner schrieb:

    fricky schrieb:

    Berufspenner schrieb:

    Solange der Code auch wirklich mit einem C-Compiler und nicht mit einem C++-Compiler übersetzt wird. Oder was meinst du damit genau?

    ich meine damit, dass er den cast weglassen kann, ja sogar besser weglassen sollte.
    🙂

    Wieso "weglassen sollte" (persönliche Neugierde 😉 )? Und ein C++-Compiler haut ihm wie gesagt eins um die Ohre, wenn er das ganze nicht castet 😉

    was ein c++, ada, java, c# oder sonstwas-compiler zu dem code sagt, ist doch völlig bedeutungslos. zum casten von malloc: http://c-faq.com/malloc/mallocnocast.html
    🙂



  • fricky schrieb:

    Berufspenner schrieb:

    fricky schrieb:

    Berufspenner schrieb:

    Solange der Code auch wirklich mit einem C-Compiler und nicht mit einem C++-Compiler übersetzt wird. Oder was meinst du damit genau?

    ich meine damit, dass er den cast weglassen kann, ja sogar besser weglassen sollte.
    🙂

    Wieso "weglassen sollte" (persönliche Neugierde 😉 )? Und ein C++-Compiler haut ihm wie gesagt eins um die Ohre, wenn er das ganze nicht castet 😉

    was ein c++, ada, java, c# oder sonstwas-compiler zu dem code sagt, ist doch völlig bedeutungslos. zum casten von malloc: http://c-faq.com/malloc/mallocnocast.html
    🙂

    Danke, endlich mal eine sinnvolle und verständliche Erklärung 🙂





  • Berufspenner schrieb:

    Wieso "weglassen sollte" (persönliche Neugierde 😉 )? Und ein C++-Compiler haut ihm wie gesagt eins um die Ohre, wenn er das ganze nicht castet 😉

    Wieso "weglassen sollte" (persönliche Neugierde 😉 )? Und ein C++-Compiler haut ihm wie gesagt eins um die Ohre, wenn SIE das ganze nicht castet 😉 😉



  • Hallo stoeoe,

    so wie ich deine Aufgabe verstehe, möchtest du eine Liste programmieren,
    die ein Objekt bestehend aus einem Namen (höchstens 9 Zeichen) und einem
    Alter verwaltet.

    Hierfür würde ich dann vielleicht einen solchen Struct definieren:

    struct Person {
        char *name;
        int   alter;
    };
    

    Und als Liste dann:

    struct Liste {
        struct Person *person;
        struct Liste  *next;
    };
    

    Um die Liste ein wenig allgemeiner zu definieren, kannst du auch soetwas
    machen:

    struct Liste {
        void *obj;
        struct Liste *next;
    };
    

    Dazu kann man dann Funktionen schreiben, die ein Element in die Liste einfügt,
    ein Element löscht, oder vielleicht ein Element ausgibt:

    struct Person *new_person(char *name, int alter);
    
    struct Liste *add_person(struct Liste *l, struct Person *p);
    ...
    

    Zum Einlesen des Namen würde ich die Funktion fgets() verwenden.
    Ihr übergibst ein Array, die Größe des Arrays und woher eingegeben wird.
    Bsp:

    char name[100];
       fgets(name, 100, stdin);
    

    fgets speichert das '\n' mit im Array. Das solltest du dann vielleicht noch
    entfernen, bevor du damit weiterarbeitest.

    Gruß mcr

    PS: deine weiteren Fehler werde ich nachher noch ansprechen.



  • Ok, dann nun zu ein paar Fehlern, die mir aufgefallen sind.

    In Zeile 43:

    } while (alter[i-1]=32);
    

    Wird die while-schleife nie abgebrochen, da du hier eine
    Zuweisung stehen hast, und eine Zuweisung immer true zurückliefert.

    Richtiger wäre:

    } while (alter[i-1]==32);
    

    Hier gibt es ein weiteres Problem:
    scanf liefert dir das Zeichen 32 (' ') nicht zurück:
    Auszug aus den Man-Pages:

    ...
     [b]Leerräume[/b] (wie [b]Leerzeichen[/b], Tabulatoren oder Zeilenumbrüche)  im  String 
     format  passen  zu  einem Freiraum  jeder  Größe,  eingeschlossen keinem 
     Freiraum, der Eingabe.
     ...
    
           s      Findet  eine  Folge von Zeichen, die [b]keinen Leerraum[/b] darstellen;
                  der nächste Zeiger muss Zeiger auf char sein, und das Feld  muss
                  groß  genug  sein um die Folge und das abschließende NUL Zeichen
                  aufzunehmen.  Der Eingabestring [b]stoppt an Leerräumen[/b] oder an der
                  maximalen Feldgrößen, je nachdem, was zuerst auftritt.
    

    Somit ist die gewollte Abbruchbedingung nicht erfüllt.

    Ein ähnliches Problem findet sich in Zeile 55. Hier weist zu dem Pointer
    die NULL zu, anstelle der Abfrage auf NULL.

    Eine mögliche Verbesserung habe ich ja schon in meinem vorangegangem Post
    beschrieben.

    Gruß mcr

    PS: ich habe nicht nach weiteren Fehlern geschaut.


Anmelden zum Antworten