Array of structure



  • Hey Leute 🙂

    habe eine neue Aufgabe vor der Brust und weiß gerade nicht so recht weiter. Die Aufgabe lautet wie folgt:

    Schreibe ein Programm, welche die Exam-Ergebnisse durch Benutzung eines 'Array of Structure' behandelt. Die Daten für ein Exam sind:
    - Mark: {0.7 - 5.0}
    - Exam identifier: {simple number, 6 digits}
    - Matriculation-No.: {simple number, 6 digits}

    Voraussetzungen:
    - Das Programm fragt nach der Anzahl der Examen
    - Deklariere eine Struktur 'exam' welche Mark, Exam-ID und Matr enthält
    - Das Programm reserviert Speicher via 'malloc' in Abhängigkeit von der Anzahl der Examen
    - Das Programm fragt für alle Examen alle Daten ab (Mark, Exam-ID, Matr)
    - Das Programm determiniert die Anzahl der bestandenen Examen (Mark <= 4.0)

    Hier ist der aktuelle Stand meines Codes:

    #include <stdio.h> 
    #define MAXMATRNUM   6  
    #define MAXEXAMIDNUM    6
    
    struct list
    {                                   
        int Matr[MAXMATRNUM]; 
        int ExamID[MAXEXAMIDNUM]; 
        float mark; 
    }; 
    
    int main() 
    { 
    
        int i;
        printf("Please enter the number of exams: ");
        scanf("%d", &i);
        struct list exams[i]; 
        int count = 0; 
        int index;
        printf("Please enter the Matriculation number: "); 
        while (count < i && gets(exams[count].Matr) != NULL  
                        && exams[count].Matr[0] != '\0' ) 
    
        { 
            printf("Now enter the exam identifier: "); 
            gets(exams[count].ExamID); 
            printf("Now enter the mark: "); 
            scanf("%f", & exams[count++].mark); 
            while (getchar() != '\n') 
                continue; 
            if (count < i) 
            printf("Enter the next Matriculation number: "); 
        } 
    
        if (count > 0) 
        { 
            printf("\nHere is the list of your Students:\n"); 
            for (index = 0; index < count; index++) 
            printf("Matriculation Number: %s \tExam ID: %s \t Mark: %.2f\n", 
            exams[index].Matr, exams[index].ExamID, exams[index].mark); 
        } 
    
        else 
              printf("No Records!\n"); 
    
        return 0; 
    }
    

    Punkt 1 und Punkt 2 der Aufgabe sind da mit drin. Punkt 3 habe ich allerdings nicht verstanden, da ich mir nicht sicher bin, wie ich malloc im Code einbinde. Punkt 4 müsste auch erfüllt sein, nur für Punkt 5 fehlt noch die if mark<=4.0 Bedingung, welche doch prinzipiell erst nach Einbindung von malloc möglich sein könnte, oder?

    Würde mich sehr über Hilfe freuen 🙂

    Mit freundlichen Grüßen



  • Tergo schrieb:

    #include <stdio.h> 
    #define MAXMATRNUM   6  
    #define MAXEXAMIDNUM    6
    
    struct list
    {                                   
        int Matr[MAXMATRNUM]; 
        int ExamID[MAXEXAMIDNUM]; 
        float mark; 
    };
    

    6 Stellen sind nicht 6 int, sondern eher 6 char.
    Diese Struct finde ich passender:

    struct list
    {                                   
        char Matr[MAXMATRNUM+1]; 
        char ExamID[MAXEXAMIDNUM+1]; 
        float mark; 
    };
    

    Das +1 ist wegen der 0 am Ende eines Strings.
    Zum Malloc: das wäre dann sowas:

    struct list *database = malloc (n * sizeof(struct list)); // n ist die Anzahl
    

    Btw, wenn malloc 0 ausspuckt, ist kein Heap-Speicher mehr frei.
    Das kann theoretisch vorkommen.



  • Hallo Andromeda 🙂

    vielen Dank für die schnelle Antwort! Der Code sähe dann jetzt so aus:

    #include <stdio.h> 
    #define MAXMATRNUM   6  
    #define MAXEXAMIDNUM    6
    
    struct list
    {                                   
        int Matr[MAXMATRNUM+1]; 
        int ExamID[MAXEXAMIDNUM+1]; 
        float mark; 
    }; 
    
    int main() 
    { 
    
        int i,n;
        struct list *database = malloc (n * sizeof(struct list));
        printf("Please enter the number of exams: ");
        scanf("%d", &i);
        struct list exams[i]; 
        int count = 0; 
        int index;
        printf("Please enter the Matriculation number: "); 
        while (count < i && gets(exams[count].Matr) != NULL  
                        && exams[count].Matr[0] != '\0' ) 
    
        { 
            printf("Now enter the exam identifier: "); 
            gets(exams[count].ExamID); 
            printf("Now enter the mark: "); 
            scanf("%f", & exams[count++].mark); 
            while 
    
    (getchar() != '\n') 
                continue; 
            if (count < i) 
            printf("Enter the next Matriculation number: "); 
    
       } 
    
        if (count > 0) 
        { 
            printf("\nHere is the list of your Students:\n"); 
            for (index = 0; index < count; index++) 
            printf("Matriculation Number: %s \tExam ID: %s \t Mark: %.2f\n", 
            exams[index].Matr, exams[index].ExamID, exams[index].mark); 
        } 
    
        else 
              printf("No Records!\n"); 
    
        return 0; 
    }
    

    Ich erhalte keine Fehlermeldungen, wenn ich jedoch die Anzahl der Examen eingegeben habe, kommt noch die Frage nach der Matrikel-Nummer, welche direkt gefolgt wird vom else-Statement: No Records!
    Beruht das darauf, dass malloc 0 rauswirft?



  • Vielleicht bin ich ja nach dem Fussballspiel noch nicht richtig wach?

    Hast du einen aktuellen Compiler und bei dem möglichst alle Fehlermeldungen aktiviert?

    scanf("%d", &i);
        struct list exams[i];
        int count = 0;
        int index;
        printf("Please enter the Matriculation number: ");
        while (count < i && gets(exams[count].Matr) != NULL  
                        && exams[count].Matr[0] != '\0' )
    
        {
            printf("Now enter the exam identifier: ");
            gets(exams[count].ExamID);
    

    In diesem Codeteil ist fast jede 2. Zeile meiner Ansicht nach verbesserungswürdig.

    MfG
    f.-th.



  • Benutze Funktionen.
    Warum sind Matr und ExamID int-Array?
    gets ist erstens für char-Arrays und zweitens böse und daher im neusten C-Standard abgekündigt. Nicht verwenden!
    Benutze Funktionen.



  • Der Compiler auf gcc.godbolt.org zeigt insgesamt zwei Fehlermeldungen an:

    Zum Einen ist malloc nicht deklariert und zum Anderen wird auch hier davon abgeraten gets zu benutzen. (malloc habe ich nun gefixt, hatte vergessen stdlib.h einzutragen)

    Prinzipiell würde ich jetzt auch zustimmen, hätte ich nicht vorher meinen Tutor gefragt, ob gets benutzt werden darf und er ja sagte. Aber gut, gets scheint hier dann wirklich nicht zu funktionieren, also versuche ich das Ganze auf Funktionen umzustricken. 🙂 Irgendwelche Tipps vorweg?



  • Momentan sieht der Code so aus:

    #include <stdio.h> 
    #include <stdlib.h>
    #define MAXMATRNUM   6  
    #define MAXEXAMIDNUM    6
    
    char getFunc(struct);
    
    struct list
    {                                   
        char Matr[MAXMATRNUM+1]; 
        char ExamID[MAXEXAMIDNUM+1]; 
        float mark; 
    }; 
    
    int main() 
    { 
    
        int result,n,i;
        struct list *database = malloc (n * sizeof(struct list));
        printf("Please enter the number of exams: ");
        scanf("%d", &i);
    
        struct list exams[i]; 
    
        result=getFunc(exams);
    
        return 0; 
    } 
    
    getFunc()
    {
        char x,y,n,i; float z;
            for(n=1; n<=i; n++)
        {
            printf("Please enter the Matriculation Number %d",n);
            scanf("%s",&x);
            printf("Please enter the Exam-ID %d",n);
            scanf("%s",&y);
            printf("Please enter the Mark %d",n);
            scanf("%f",&z);
        }
        return x,y,z;
    }
    

    Der Code kann auch ausgeführt werden, nach der Frage, wieviele Examen ich eingeben möchte, beendet sich das Programm allerdings automatisch 😕



  • Tergo schrieb:

    Der Compiler auf gcc.godbolt.org zeigt insgesamt zwei Fehlermeldungen an:

    Zum Einen ist malloc nicht deklariert und zum Anderen wird auch hier davon abgeraten gets zu benutzen. (malloc habe ich nun gefixt, hatte vergessen stdlib.h einzutragen)

    Prinzipiell würde ich jetzt auch zustimmen, hätte ich nicht vorher meinen Tutor gefragt, ob gets benutzt werden darf und er ja sagte. Aber gut, gets scheint hier dann wirklich nicht zu funktionieren, also versuche ich das Ganze auf Funktionen umzustricken. 🙂 Irgendwelche Tipps vorweg?

    Nimm statt gets() besser fgets(), denn das hat eine Längenbegrenzung.
    Dein Code mit dem malloc() ist auch nicht richtig. Es muss ungefähr so aussehen:

    ...
        int n;
        struct list *database;
        printf("Please enter the number of exams: ");
        scanf("%d", &n);
        database = malloc (n * sizeof(struct list));
        if (database == 0)
            return EXIT_FAILURE; // malloc schlug fehl
    
        ... // Dein restlicher Code
    
        // ... und am Ende
        free (database);
        return EXIT_SUCCESS;
    

    Den Pointer "database" darfst du nicht verändern, sonst geht free() nicht. Also am besten nur über Index ([]) darauf zugreifen (wie man das mit Arrays macht).



  • Vielen Dank für die Antwort 🙂

    Dann sieht der Code jetzt so aus:

    #include <stdio.h> 
    #include <stdlib.h>
    #define MAXMATRNUM   6  
    #define MAXEXAMIDNUM    6
    
    char getFunc(struct);
    
    struct list
    {                                   
        char Matr[MAXMATRNUM+1]; 
        char ExamID[MAXEXAMIDNUM+1]; 
        float mark; 
    }; 
    
    int main() 
    { 
        int n,result,i;
        struct list *database;
        printf("Please enter the number of exams: ");
        scanf("%d", &n);
        database = malloc (n * sizeof(struct list));
        if (database == 0)
            return EXIT_FAILURE;
    
        struct list exams[i]; 
    
        result=getFunc(exams);
    
        return 0; 
    
        free (database);
        return EXIT_SUCCESS;
    } 
    
    char getFunc()
    {
        char x,y,n,i; float z;
            for(i=1; i<=n; i++)
        {
            printf("Please enter the Matriculation Number %d",i);
            scanf("%s",&x);
            printf("Please enter the Exam-ID %d",i);
            scanf("%s",&y);
            printf("Please enter the Mark %d",i);
            scanf("%f",&z);
        }
        return x,y,z;
    }
    

    Jedoch wird mir mitgeteilt, dass die Variablen der unteren Funktion nicht deklariert seien. Wie kann das sein? Schließlich sind diese doch als char/float deklariert.



  • Tergo schrieb:

    Der Compiler auf gcc.godbolt.org zeigt insgesamt zwei Fehlermeldungen an:

    Zum Einen ist malloc nicht deklariert und zum Anderen wird auch hier davon abgeraten gets zu benutzen. (malloc habe ich nun gefixt, hatte vergessen stdlib.h einzutragen)

    Fehlermeldungen sagen Nichts darüber aus, ob das Programm richtig ist.
    Warnungen sind genauso wichtig, aber auch die sind kein hinreichender Grund für ein fehlerfreies Programm.

    Tergo schrieb:

    Prinzipiell würde ich jetzt auch zustimmen, hätte ich nicht vorher meinen Tutor gefragt, ob gets benutzt werden darf und er ja sagte.

    Dann überleg mal, was du von weiteren Aussagen des Tutors halten kannst.

    Tergo schrieb:

    Aber gut, gets scheint hier dann wirklich nicht zu funktionieren, also versuche ich das Ganze auf Funktionen umzustricken. 🙂 Irgendwelche Tipps vorweg?

    Da verwechselst du aber Einiges.
    Dass du gets falsch benutzt hat nichts damit zu tun, dass man es nicht verwenden soll.
    Auch der Verzicht auf gets hat nichts mit der Aufteilung deines Programms in Funktionen zu tun.

    Statt gets kann man auch andere Standardfunktionen verwenden. Aber auch die wollen char -Arrays.

    %s bei scanf funktioniert nicht mit einem char
    Eine Funktion kann nur einen Wert zurück geben (eine struct ist ein Wert)

    Vergib vernünftige (sprechende) Namen für deine Funktionen.
    Lass sie nur das machen, was auch der Name verspricht.
    Mach sie nicht zu komplex.
    In die Parameterliste der Funktion gehört der Typ und der Name der Variablen. ( struct ist keines von Beiden)



  • Tergo schrieb:

    struct list exams[i];
    

    Was hast du denn damit vor?
    Das struct list Array baust du dir doch schon mit malloc().

    Tergo schrieb:

    result=getFunc(exams);
             
        return 0;
       
        free (database);
        return EXIT_SUCCESS;
    

    Das "return 0;" verhindert, dass der Code darunter jemals dran kommt.
    Sorry, aber ich glaube, du hast bezüglich der C-Grundlagen noch massive Defizite.
    😞



  • Andromeda schrieb:

    Nimm statt gets() besser fgets(), denn das hat eine Längenbegrenzung.

    Aber gets und fgets kann man nicht 1:1 austauschen, da fgets noch das '\n' von der Entertaste abspeichert.

    Zudem ist das mischen von scanf und fgets für Anfänger schwierig.
    Hier spricht nichts dagegen, nur scanf zu nehmen. Aber man muss auf die richtigen Paramter achten und sollte auch die Länge mit angeben.
    Dabei muss man aber beachten, dass immer noch Platz für die '\0' bleibt.



  • Ich weiß leider um die Defizite, aber genau aus dem Grund bin ich hier 🙂 dies ist der letzte Informatik-Kurs in meinem Studium und die Aufgaben sind auch nicht zum Erledigen des Kurses notwendig, allerdings würde ich es dennoch gerne verstehen und dachte, ich komme hierhin 🙂

    Ich tüftel gerade noch am Code, habe etwas umdispuniert. Danke Dirk für die zahlreichen Anmerkungen 🙂



  • DirkB schrieb:

    Andromeda schrieb:

    Nimm statt gets() besser fgets(), denn das hat eine Längenbegrenzung.

    Aber gets und fgets kann man nicht 1:1 austauschen, da fgets noch das '\n' von der Entertaste abspeichert.

    Stimmt, scanf ("%6s" ...) finde ich auch besser. 🙂



  • Aktuell sieht es so aus:

    #include <stdio.h> 
    #include <stdlib.h>
    #define MAXMATRNUM   6  
    #define MAXEXAMIDNUM    6
    
    char Display(char,char,float);
    
    struct list
    {                                   
        char Matr[MAXMATRNUM+1]; 
        char ExamID[MAXEXAMIDNUM+1]; 
        float mark[]; 
    }; 
    
    int main() 
    { 
        int n,result,i;
        struct list *database;
        printf("Please enter the number of exams: ");
        scanf("%d", &n);
        database = malloc (n * sizeof(struct list));
        if (database == 0)
            return EXIT_FAILURE;
    
        struct list exams[n];
    
        for(n=0; n<i; n++)
        {
            printf("Please enter the Matriculation Number %d",i);
            scanf("%c",&exams[n].Matr);
            printf("Please enter the Exam-ID %d",i);
            scanf("%c",&exams[n].ExamID);
            printf("Please enter the Mark %d",i);
            scanf("%f",&exams[n].mark);
        }
    
        result=Display(Matr,ExamID,mark);
    
        free (database);
        return EXIT_SUCCESS;
    } 
    
    char Display(char x,char y, float z)
    {
        if(exams[n].mark<=4.0)
    
        return 0;
    }
    

    Wenn ich mir den Code ansehe, ist es eigentlich schon eher das, wo ich hin wollte. Eine Frage habe ich allerdings bezüglich der Display-Funktion? Wie schaffe ich es, gewisse Daten einer Struktur in dieser Funktion auf ihre Wertigkeit zu testen? Dass es wie oben falsch ist, sehe ich ein 😃



  • Tergo schrieb:

    Wenn ich mir den Code ansehe, ist es eigentlich schon eher das, wo ich hin wollte.

    Kannst du das denn überhaupt beurteilen?

    Tergo schrieb:

    Eine Frage habe ich allerdings bezüglich der Display-Funktion? Wie schaffe ich es, gewisse Daten einer Struktur in dieser Funktion auf ihre Wertigkeit zu testen? Dass es wie oben falsch ist, sehe ich ein 😃

    Der Test ist richtig. Nur solltest du auch in der Funktion Zugriff auf das Array haben.

    %c bei scanf mit einem char-Array ist selten sinnvoll.
    Wozu dient database und wozu ist exam da?

    Was hat der Begriff 'Display' mit dem Test auf bestandene Tests zu tun?
    - scheint der falsche Name für die Funktion zu sein.



  • 1. Die Funktion heißt nun 'passedTest'.
    2. Database, so dachte ich, gehört zur Deklarierung von malloc.
    3. Exams hatte ich eingeführt, um die gescannten Daten auf die Struktur zu katalogisieren.
    4. Wie kann ich in der Funktion denn auf ein Array zugreifen? Kommt dann in die Klammer, einfach dasselbe wie in Zeile 37?

    #include <stdio.h> 
    #include <stdlib.h>
    #define MAXMATRNUM   6  
    #define MAXEXAMIDNUM    6
    
    char passedTest(char,char,float);
    
    struct list
    {                                   
        char Matr[MAXMATRNUM+1]; 
        char ExamID[MAXEXAMIDNUM+1]; 
        float mark[]; 
    }; 
    
    int main() 
    { 
        int n,result,i;
        struct list *database;
        printf("Please enter the number of exams: ");
        scanf("%d", &n);
        database = malloc (n * sizeof(struct list));
        if (database == 0)
            return EXIT_FAILURE;
    
        struct list exams[n];
    
        for(n=0; n<i; n++)
        {
            printf("Please enter the Matriculation Number %d",i);
            scanf("%c",&exams[n].Matr);
            printf("Please enter the Exam-ID %d",i);
            scanf("%c",&exams[n].ExamID);
            printf("Please enter the Mark %d",i);
            scanf("%f",&exams[n].mark);
        }
    
        result=passedTest(exams[n].Matr,exams[n].ExamID,exams[n].mark);
    
        free (database);
        return EXIT_SUCCESS;
    } 
    
    char passedTest(exams[n].Matr,exams[n].ExamID,exams[n].mark)
    {
        if(exams[n].mark<=4.0)
    
        return 0;
    }
    


  • Wozu dient malloc und warum benutzt du es?

    Lies, Nein, arbeite dein Vorlesungsscripz nochmal, besser mehrmals, durch.

    Wenn das nicht reicht, hol dir ein Buch über C. Gibt es auch in der Bibliothek.

    Du hast so große Defizite, dass du eine Privatvorlesung brauchst.
    Diese Zeit haben hier die Allerwenigsten.



  • Danke für den Tipp, werde ich definitiv machen! Allerdings benötige ich bis Dienstag die Lösung zu der Aufgabe 😞



  • Tergo schrieb:

    Allerdings benötige ich bis Dienstag die Lösung zu der Aufgabe 😞

    Die wird hier aber keiner machen.
    Das ist deine Aufgabe.

    Ihr müßt ja irgendwann mal Arrays behandelt haben. Möglicherweise als es um C-Strings ging.
    Auch Funktionen, die Arrays als Paramter haben, werden da i.A. behandelt.
    Schau da doch mal nach.

    Im übrigen übergibst du einzelne Elemente der struct an die Funktion.


Log in to reply