Pointer auf struct



  • hallo leute ich hoffe ihr könnte mir weiterhelfen. ich hab noch nicht so viel ahnung mit pointern und malloc, realloc usw. kann mir vielleicht jemand sagen wieso das nicht funktioniert. ich will einfach nur einlesen und ausgeben.

    struct namen{
    char name[100];
    int age;
    };

    int main()
    {
    struct namen *adresse;
    adresse=malloc(sizeof(struct namen));

    printf("name: "); scanf("%s", adresse.name);
    printf("age: "); scanf("%d", adresse.age);

    printf("%s und %d", adresse.name, adresse.age);

    return 0;
    }



  • Bei Zeigern auf structs musst du -> statt . nehmen.
    Außerdem braucht scanf einen Zeiger auf das age

    struct namen{
    char name[100];
    int age;
    };
    
    int main()
    {
    struct namen *adresse;
    adresse=malloc(sizeof(struct namen));
    
    printf("name: "); scanf("%s",   adresse->name);
    printf("age : "); scanf("%d", &(adresse->age));
    
    printf("%s und %d", adresse->name, adresse->age);
    
    return 0;
    }
    


  • Und wenn du schon dabei bist, ein free(adresse); , zum Beispiel vor return , würde auch nicht schaden.
    Auch würde ich die Länge für den String in scanf auf die Array-Größe beschränken. Ich denke das geht mit scanf("%99s", adresse->name); , bin mir da aber jetzt nicht sicher.



  • sei Dir sicher "Nick Unbekannt", das ist so 🙂
    http://www.cplusplus.com/reference/clibrary/cstdio/scanf/



  • Wow ich danke euch viel..vielmals für die schnellen Antworten! Ich habe das Programm fast fertig nur habe ich noch einige Fehler auf die ich keine logische Erklärung finde leider.

    1. Zeile 39 (MARKIERT)... (eintraege+2) wieso geht es nicht mit +1 wenn eintraege sowieso bei jedem Eintrag erhöht wird.
    2. Zeile 57 (MARKIERT) funktioniert nicht so ganz wie ich das möchte. Die for schleife wird nicht ausgeführt und wenn ich die Klammer nach der else setze schreibt er mir logischerweise immer "Kein Eintrag gefunden" wenn mehrere Namen durchgesucht werden.
    3. Zeile 70 (MAKRIERT) würde es so stimmen mit der Funktion free das ich jedes einzelne Element löschen sollte?
    4. Könnte ich char name[100] in der Struktur auch so dynamisch gestalten, sodass die länge vom Namen beliebig lang ist?
    5. Ach ja und hat das noch was mit Pointern zu tun wenn ich adresse[eintraege].name schreibe und nicht adresse->name? Weil sonst kann ich ja nicht auf alle Einträge zugreifen soweit ich das verstehe.

    Ich weiss das ist etwas viel ich bin aber wirklich dabei so viel wie möglich alleine zu erlernen!!
    Ich danke im Voraus

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    struct namen{
    char name[100];
    int age;
     };
    
    int main()
    {
        int i=0;
        int eintraege=0;
        int eingabe;
        char suche_name[100];
        struct namen *adresse;
        adresse=malloc(sizeof(struct namen));
    
        if(adresse==0)
        {
            printf("Speicherreservierung nicht möglich\n");
        }
    
    while(1)
    {
        printf("\n");
        printf("1.. Namen hinzufuegen\n");
        printf("2.. Alle Namen anzeigen\n");
        printf("3.. Einen Namen suchen\n");
        printf("4.. Exit\n");
    
        printf("eingabe: "); scanf("%d", &eingabe);
        printf("\n");
    
        if(eingabe==1)
        {
            printf("name: "); scanf("%s",   adresse[eintraege].name);
            printf("age : "); scanf("%d", &adresse[eintraege].age);
            adresse = realloc(adresse, sizeof(struct namen)*(eintraege+2)); //Zeile 39 <-------
    
            eintraege++;
        }
    
        if(eingabe==2)
        {
            for(i=0;i<eintraege;i++)
            {
                printf("name: %s\n", adresse[i].name);
                printf("age: %d", adresse[i].age);
                printf("\n");
            }
    
        }
        if(eingabe==3)
        {
            printf("Gewuenschter Name: "); scanf("%s", &suche_name);
                for(i=0;i<eintraege;i++)             //ZEILE 57 <--------------
            {
                if(strcmp(suche_name,adresse[i].name)==0)
                {
                    printf("%s (%d)\n",adresse[i].name, adresse[i].age);
                }
            }
                else
                {
                    printf("Kein Eintrag gefunden\n");
                }
    
        }
        if(eingabe==4)          //ZEILE 70 <-----------------
        {
            for(i = 0; i < eintraege; i++)      
                {
                    free(adresse[i].name);      
                    free(adresse[i].age);
                }
                    free(adresse);
            break;
        }
    
    }
    return 0;
    }
    


  • zu Zeile 39: einträge == 0, also einträge +1 = 1, d.h. Du hast ein Speicherplatz schon reserviert; wenn Du noch einen möchtest dann +1, d.h. +2 😉
    zu Zeile 57: Du setzt voraus, das alles sequentiell abgearbeitet wird. Einträge ist am Anfang == 0. Was ist wenn einer Daten abfragen will und noch keine eingeben hat?
    zu Zeile 70: Ein einfaches "free(adresse)" reicht, da Du in der Struct Adresse keine weiteren Elemente dynamisch allokiert hast, d.h namen und age haben hardcodet (festgelegte) Werte.
    Mit adresse->namen liest Du den ersten wert aus == adresse[0].namen ... schwitzen um diese Uhrzeit... 🕶



  • super ich danke vielmals für die ausführlich erklärung! könnte ich nun auch den aus dem name[100] in der struct ein *name machen und es so für die namen eingabe auch dynamisch gestalten ?



  • Ja, dann brauchst du aber wieder Zeile 74 (free(adresse[i].name);).



  • nein ich meine das so: jetzt kann ich ja einen namen eingeben der der [100] groß ist. das heisst es wird ja unnötig viel speicher verbraucht. wenn ich nur r [0] u [1] d [2] i [3] 4 [\0] eingebe bleiben mir ja [5] -[99] frei. wie könnte ich das machen das auch hier nur so viel speicher reserviert wird, wie wirklich nötig?



  • so hätte ich das gemeint:
    in der struct steht nun *name
    int puffer[80]
    und beim einlesen ab (eingabe==1):
    printf("name: "); scanf("%s", puffer);
    adresse[eintraege].name=strdup(puffer);
    das wäre ja dann dynamischER oder nicht.

    liebe Grüße



  • Ja, das meinte ich auch.
    Nur musst du Speicher von strdup auch mit free freigeben.
    Jeden von strdup angeforderten Speicher.
    So wie in deinem Code oben in Zeile 74:

    for(i = 0; i < eintraege; i++)      
            {
              free(adresse[i].name);    // von strdup oder malloc  
    //        free(adresse[i].age); 
            }
            free(adresse);
    

    Aber bevor du jetzt weiter mit realloc rummachst, schau dir (doppelt-)verkettete Listen an.


Anmelden zum Antworten