Probleme mit dem Ändern von Werten in einem Struct



  • Hallo liebe Programmierer...
    Ich bin noch recht neu in C und wenn ich ehrlich bin bekomme ich einiges noch nicht so ganz auf den Schrirm^^

    Meine Aufgabe ist es ein Konsolenprogramm mit C zu schreiben, welches für eine Turnierverwaltung fungiert. Bisher klappte auch alles soweit wie ich kam, doch jetzt stoße ich an meine Grenzen des Verständnisses...

    Ich habe einen Header in dem Vorab alles deklariert wird:

    struct team {
      char name[MAX];
      unsigned short group;
      unsigned short goals;
      unsigned short agoals;
      unsigned short points;
      int edit;
    };
    
    struct teams {
      struct team team[ANZAHL];
    };
    struct game {
      char team1[MAX];
      char team2[MAX];
      unsigned short tore1;
      unsigned short tore2;
      int team1_id;
      int team2_id;
    };
    
    struct group {
      struct game game[ANZAHL];
    };
    
    size_t start, cur;
    int game_id,i, i_file, i_grp, i_grp_phs, i_game, i_tbl, j, grp, len, random;
    char eingabe;
    char input[MAX],input2[MAX],temp2[MAX], file[MAX], team_file[MAX], config_file[MAX], tournament_file[MAX], temp[MAX], game_phase[MAX];
    char *token[200];
    

    Jetzt habe ich eine Funktion in der man die Ergebnisse der Spiele eintragen kann. Basierend auf der i_game variable und der i_grp variable die der Funktion beim Aufruf übergeben wird, wird die Funktion auch ohne Fehler der Compilers abgearbeitet...

    void set_score(struct teams teams, struct group group[50],int i_game,int i_grp){
        clear_screen();
        ascii_art_tournament_mode();
        printf("\n\t\t  ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»");
        printf("\n\t\t  º  Spielergebnis fuer Spiel eintragen  º");
        printf("\n\t\t  ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n");
        printf("\n\t\t    Eintrag vom Ergebnis %s gegen %s\n\n",group[i_grp].game[i_game].team1,group[i_grp].game[i_game].team2);
        printf("\t\t\tWieviel Tore hat %s erzielt? ",group[i_grp].game[i_game].team1);
        fgets(input,MAX,stdin);
        for (i=0 ; i<strlen(input)-1 ; i++)
        {
            if (!isdigit(input[i]))
            {
                printf("\n\n\t\t\tNur Zahlen als Eingabe erlaubt!\n\n\t\t\t") ;
                system("pause");
                set_score(teams,group,i_game,i_grp);
            break ;
            }
        }
        len = strlen(input);
        if(input[len-1] == '\n' ) input[len-1] = 0;
        group[i_grp].game[i_game].tore1=atoi(input);
        printf("\t\t\tWieviel Tore hat %s erzielt? ",group[i_grp].game[i_game].team2);
        fgets(input2,MAX,stdin);
        for (i=0 ; i<strlen(input2)-1 ; i++)
        {
            if (!isdigit(input2[i]))
            {
                printf("Nur Zahlen als Eingabe erlaubt!\n") ;
                set_score(teams,group,i_game,i_grp);
            break ;
            }
        }
        len = strlen(input);
        if(input2[len-1] == '\n' ) input2[len-1] = 0;
        group[i_grp].game[i_game].tore2=atoi(input2);
        if(atoi(input2)>atoi(input)){
            teams.team[group[i_grp].game[i_game].team2_id].points+=3;
        }
        else if(atoi(input2)<atoi(input)){
            teams.team[group[i_grp].game[i_game].team1_id].points+=3;
        }
        else{
            teams.team[group[i_grp].game[i_game].team1_id].points+=1;
            teams.team[group[i_grp].game[i_game].team2_id].points+=1;
        }
        printf("%i %i\n",teams.team[0].points,teams.team[1].points);
        return teams,group;
    }
    

    Jedoch werden nur die Daten im struct group aktualisiert.
    Die Daten die im struct teams verändert werden, werden nach dem Beenden der Funktion verworfen. Nun verstehe ich überhaupt nicht warum die Daten in struct group gespeichert werden und in struct teams eben nicht 😞
    Überprüft habe ich das durch das printf am Ende der Funktion (da stimmen die Werte) und einem weiteren printf (hier nicht zu sehen) die nach der Funktion aufgerufen wird (da stimmen die Werte nicht mehr - sondern sind weiterhin bei der Vorgabe 0)

    Vielleicht kann mir ja jemand von euch helfen 🙂

    P.S.: Bei Bedarf stelle ich natürlich auch mehr Code zur Verfügung 😉



  • Kannst du den Code kompilieren?

    Sowas hier sollte der Compiler eigentlich nicht durchgehen lassen 😉

    return teams,group;
    

    Mit dem "return"-Befehl kannst du generell nur EINE Variable zurückgeben.

    Zur Rückgabe von mehreren Werten solltest du dir mal das Stichwort "Call-by-reference" anschauen.



  • Bei group funktioniert das, weil group ein Array ist und somit intern automatisch eine Adresse. Somit übergibst du dabei quasi nur eine Adresse an die Funktion und er kann den Inhalt hinter der Adresse verändern.

    Bei teams übergibst du den Wert direkt und nicht die Adresse des Structs. Somit wird dort beim Funktionsaufruf eine Kopie deiner Struktur angelegt. Somit ändert sich teams außerhalb der Funktion logischerweise nicht.



  • Ja, das lässt er durchgehen.

    Nur, auch wenn ich das return weglasse... Ändert er nur den Wert im struct group und nicht im struct teams.

    Deshalb stehe ich auf dem Schlauch.

    Das return teams,group; war nur von meinen letzten Versuchen das iwie anders hinzubekommen noch drin...

    Wieso übernimmt er denn nur die Werte vom struct group? Und nicht vom struct teams?



  • Mache aus

    void set_score(struct teams teams, struct group group[50],int i_game,int i_grp)
    

    ein

    void set_score(struct teams *teams, struct group group[50],int i_game,int i_grp)
    

    und übergebe die Adresse von teams mit &teams . Vielleicht klappte es ja dann schon.



  • Nicht nur vielleicht. Ganz sicher wird es klappen 😉



  • Und gewöhne dir mal an, deinen Variablen nicht den gleichen Namen zu geben, wie deinen Strukturen. 😉



  • Ich vermute einfach mal, dass es sich in C mit dem , wie in C++ verhält, das heißt er gibt immer das letzte Element zurück.



  • Also ich habe gerade nur den BCB6.0 am Wickel und der erlaubt zwar Kommata bei return-Kommandos, aber nicht, wenn die Funktion einen Rückgabewert "void" hat, so wie im Beispiel des TE 😃



  • dirty little helper schrieb:

    Sowas hier sollte der Compiler eigentlich nicht durchgehen lassen 😉

    return teams,group;
    

    Ist das so? Evaluiert nicht teams,group zum Wert von group ?



  • Ja, aber macht das Sinn, sowas durchgehen zu lassen?
    Meines Erachtens nicht.



  • It0101 schrieb:

    Ja, aber macht das Sinn, sowas durchgehen zu lassen?
    Meines Erachtens nicht.

    Meines Erachtens nach gehört der ganze Kommaoperator in den Reißwolf. Aber wenn man ihn hat, dann bitte auch überall. Sonst würde die Sprache anfangen, unübersichtlich zu werden.

    Und nach

    #ifdef PERFORMANCELOG
    #define READ(x)(++readCount,x)
    #else
    #define READ(x)(x)
    #endif
    

    zum Ausmessen von Lese/Schreibzugriffen von Algorithmen, dann schreibt sucher auch jemand

    {
       return GET(arr[0]);
    

    und schon hätten wir den Salat, wenn der Kommaoperator im return verboten wäre.



  • It0101 schrieb:

    Ja, aber macht das Sinn, sowas durchgehen zu lassen?
    Meines Erachtens nicht.

    Du würdest also an der Syntax herumfrickeln, nur um den Komma-Operator in einem return zu verbieten? Dann wäre C eine B&D-Sprache.

    Macht es Sinn, sowas zu verbieten?

    if (i = 10) do_something();
    


  • mngbd schrieb:

    Dann wäre C eine B&D-Sprache.

    Was ist eine B&D-Sprache?



  • volkard schrieb:

    Meines Erachtens nach gehört der ganze Kommaoperator in den Reißwolf.

    Ich verwende ihn schon seit langem nur noch für sowas wie a++, b++ in for-Schleifen. Aber dort möchte ich ihn nicht vermissen, sonst müsste man im for-Kopf Blöcke erlauben.



  • volkard schrieb:

    Was ist eine B&D-Sprache?

    Ich hatte das hier im Hinterkopf:
    http://catb.org/jargon/html/B/bondage-and-discipline-language.html

    Aber sehr verbreitet ist der Ausdruck nicht.



  • mngbd schrieb:

    volkard schrieb:

    Meines Erachtens nach gehört der ganze Kommaoperator in den Reißwolf.

    Ich verwende ihn schon seit langem nur noch für sowas wie a++, b++ in for-Schleifen. Aber dort möchte ich ihn nicht vermissen, sonst müsste man im for-Kopf Blöcke erlauben.

    Stimmt, an der Stelle macht der Kommaoperator natürlich schon Sinn.
    Das Beispiel hatte ich nicht bedacht.

    Es würde aber auch ohne ihn gehen 😉 Gibt ja im Notfall auch noch andere schleifen 😃


Log in to reply