Array of structure



  • 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.



  • Ich glaube ich verstehe jetzt, wieso 'exams' falsch gewählt war. Database war ja schließlich bereits deklariert, richtig?

    #include <stdio.h> 
    #include <stdlib.h>
    #define MAXMATRNUM   6  
    #define MAXEXAMIDNUM    6
    
    char passedTest(struct list database);
    
    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;
    
        for(n=0; n<i; n++)
        {
            printf("Please enter the Matriculation Number %d",i);
            scanf("%c",&database[n].Matr);
            printf("Please enter the Exam-ID %d",i);
            scanf("%c",&database[n].ExamID);
            printf("Please enter the Mark %d",i);
            scanf("%f",&database[n].mark);
        }
    
        result=passedTest(database);
    
        printf("The number of passed exams is: %d", result);
    
        free (database);
        return EXIT_SUCCESS;
    } 
    
    char passedTest(struct list database)
    {
        int num;
        if(exams[n].mark<=4.0)
    
        return 0;
    }
    

    Den einzigen Error, den ich jetzt noch AUßERHALB der unteren Funktion erhalte, ist, dass der Typ von passedTest Konflikte bereitet. Dieser ist aber, wie oben, char.

    Edit: habe schon mal angefangen, das Endergebnis letztendlich abzudrucken. Das einzige, was nun noch fehlt, ist der Test in der Funktion 😞



  • Du hast jetzt zweimal database definiert.
    Einmal als Pointer und einmal als Array.
    Das mag der Compiler nicht.

    Du übergibst auch dieses database an die Funktion passedTest. Die erwartet aber ein struct und keine Adresse (Zeiger) darauf. Großer Unterschied!


Anmelden zum Antworten