Thread: Saving corrupts my database.

  1. #1
    Registered User JamesM's Avatar
    Join Date
    Sep 2003
    Posts
    18

    Question Saving corrupts my database.

    My program runs fine. It generates the results from all games within a league with a bias for each team, compiles a league table and displays it. Gives a report on the season and promotes a team. I'm not sure if it's the swaping of teams or the saving that's the problem or a combination thereof.

    Basically, when you are asked if you want to play another season you can press s to save some data. If you do this, the team name of the relegated team is corrupted. I'm getting really confused as I've played around with the code and got different results:
    The team name was being corrupted in memory.
    The team name is now just corrupted in the save file.
    I know some of my formatting isn't great and my comments aren't quite what they could be but any ideas?!?

    Code:
    /*  
     *  Based on kickoff.c
     *  Generates a full results list, sorted
     *  league table and seasonal report.
     *  Relegates the bottom team and promotes
     *  another. Prompts for further seasons.
     */ 
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    int pickteam(int);
    int checkteams(int, int);
    int setteams();
    void startmatch(int, int);
    int scoringteam(int, int, int, int);
    void initleague(int);
    void fillinleague(int, int, int, int);
    void displayleague(int, int);
    int league[9][8];
    void sortleague(int);
    void doseason(int);
    void dostats();
    void swapbottom();
    int yn();
    typedef struct
    {
        char *name;
        int quality;
        int wins;
        int rel;
    } teamType;
    teamType teams[8];
    FILE *statsfile;
    
    int main()
    {
        int year=0, another=1;                            /* Initialise invalid team selection */
        srand( (unsigned)time( NULL ) );
        srand( (unsigned)1000*rand()/RAND_MAX );                /* Randomise several times */
        srand( (unsigned)1000*rand()/RAND_MAX );                /* for random scores       */
        setteams();
        doseason(year);
        while (another == 1)
        {
            another = yn();
            year++;
            if (another == 1) doseason(year);
        }
        return 0;
    }
    
    int yn()
    {
        char answer, answer2;
        int done;
        done = 0;
        while(done==0)
        	{
            printf("Do you want to play another season?");
            printf("\nEnter Y for yes, N for no:");
            // scanf("%c", answer);
            answer=getch();
            answer2=toupper(answer);
            printf(" %c", answer);
            if (answer2=='Y'||answer2=='N')
                done=1;
            if (answer2=='S')
                dostats();
        }
        if (answer2=='Y')
            return 1;
        else return 0;
    }
    
    void doseason(int year)
    {
        int team1, team2;
        initleague(0);
        for (team1 = 0; team1 < 8; team1++)
        {
            for (team2 = 0; team2 < 8; team2++)
            {
                if (team1 != team2) startmatch(team1, team2);
            }
        }
        sortleague(8);
        displayleague(8, year);
        swapbottom();
    }
    
    int pickteam(int team1)
    {
        int team=999, y;                             /* Initialise returning integer */
        for (y=1;y<=8;y++)                           /* Display team list */
        {
            if (y != team1)
            {
                printf("%d ", y);
                printf("%s", teams[y].name);
                printf("\n");
            }
        }
        while (team > 9)
        {
            scanf("%i", &team);                      /* Wait for input */
        }
        return team;                                 /* Return team selected */
    }
    
    int checkteams(int team1, int team2)
    {
        while (team1 == team2)                       /* Check for duplicate team */
        {
            printf("You cannot play with yourself here!\nYour first team is ");
            printf("%s", teams[team1].name);
            printf("(%i). Please enter a second team:\n", team1); /* Warn against duplicate team */
            team2 = pickteam(team1);                              /* Call pickteam subroutine */
        }
        return team2;
    }
    
    int setteams()
    {
        /* Sets values are each teams' quality. For example:          */
        /* Arsenal, Man Utd, Bradford and Newcastle are superb teams. */
        /* Leeds and Hull average, Farsley Celtic and Guiseley poor.  */
        teams[0].name = "Arsenal FC";
        teams[0].quality = 5;
        teams[0].wins = 0;
        teams[0].rel = 0;
    
        teams[1].name = "Newcastle Utd";
        teams[1].quality = 5;
        teams[1].wins = 0;
        teams[1].rel = 0;
    
        teams[2].name = "Manchester Utd";
        teams[2].quality = 5;
        teams[2].wins = 0;
        teams[2].rel = 0;
    
        teams[3].name = "Bradford City";
        teams[3].quality = 6;
        teams[3].wins = 0;
        teams[3].rel = 0;
    
        teams[4].name = "Leeds United";
        teams[4].quality = 4;
        teams[4].wins = 0;
        teams[4].rel = 0;
    
        teams[5].name = "Hull City";
        teams[5].quality = 3;
        teams[5].wins = 0;
        teams[5].rel = 0;
    
        teams[6].name = "Guiseley";
        teams[6].quality = 2;
        teams[6].wins = 0;
        teams[6].rel = 0;
    
        teams[7].name = "Farsley Celtic";
        teams[7].quality = 2;
        teams[7].wins = 0;
        teams[7].rel = 0;
    
        teams[8].name = "Pub 5-a-side";
        teams[8].quality = 1;
        teams[8].wins = 0;
        teams[8].rel = 0;
    
        return 0;
    }
    
    void startmatch(int team1, int team2)
    {
        int team1val, team2val, goals, var, whoscored, team1goals = 0, team2goals = 0;
        team1val = teams[team1].quality;
        team2val = teams[team2].quality;
        goals = (int) 6 * rand()/RAND_MAX;            /* Set number of goals in match (0 - 6) */
        for (var = 0; var<= goals; var++)
        {
            whoscored = scoringteam(team1, team1val, team2, team2val); /* Determine who scored */
            if (whoscored == team1) team1goals++;
            else team2goals++;                                     /* Increment relevent score */
        }
        printf("%s", teams[team1].name);
        printf(" %i - %i ", team1goals, team2goals);               /* Display result */
        fillinleague(team1, team1goals, team2, team2goals);
        printf("%s", teams[team2].name);
        printf("\n");
    }
    
    scoringteam(int team1, int team1val, int team2, int team2val)
    {
        if (((float) rand()/RAND_MAX) >= ((float)team1val / (team1val + team2val))) return team2;
        else return team1;
    }
    
    void initleague(int start)
    {
        int var1, var2;
        for (var1 = 0; var1<9; var1++)
        {
            for (var2 = 0; var2<8; var2++)
            {
                if (var2 == 0)
                    league[var1][var2] = (var1);
                else
                    league[var1][var2] = start;
            }
        }
    }
    
    void fillinleague(team1, team1goals, team2, team2goals)
    {
        league[team1][1] = league[team1][1] + 1;
        league[team2][1] = league[team2][1] + 1;
        league[team1][5] = league[team1][5] + team1goals;
        league[team2][6] = league[team2][6] + team1goals;
        league[team2][5] = league[team2][5] + team2goals;
        league[team1][6] = league[team1][6] + team2goals;
        if (team1goals > team2goals)
        {
            league[team1][2] = league[team1][2] + 1;
            league[team1][7] = league[team1][7] + 3;
            league[team2][3] = league[team2][3] + 1;
        }
        else if (team1goals < team2goals)
        {
            league[team2][2] = league[team2][2] + 1;
            league[team2][7] = league[team2][7] + 3;
            league[team1][3] = league[team1][3] + 1;
        }
        else if (team1goals == team2goals)
        {
            league[team1][4] = league[team1][4] + 1;
            league[team2][4] = league[team2][4] + 1;
            league[team1][7] = league[team1][7] + 1;
            league[team2][7] = league[team2][7] + 1;
        }
    }
    
    void sortleague(int noteams)
    {
        int x, y, z, t[9];
        for (x=0; x < noteams; x++)
        {
            for (y=0; y < noteams-x; y++)
            {
                if (league[y][7] < league[y+1][7])
                {
                    for (z=0; z < 8; z++)
                    {
                        t[z]=league[y][z];
                        league[y][z]=league[y+1][z];
                        league[y+1][z]=t[z];
                    }
                }
                if (league[y][7] == league[y+1][7])
                {
                    if (league[y][5] < league[y+1][5])
                    {
                        for (z=0; z < 8; z++)
                        {
                            t[z]=league[y][z];
                            league[y][z]=league[y+1][z];
                            league[y+1][z]=t[z];
                        }
                    }
                    if (league[y][5] == league[y+1][5])
                    {
                    if (league[y][6] > league[y+1][6])
                        {
                            for (z=0; z < 8; z++)
                            {
                                t[z]=league[y][z];
                                league[y][z]=league[y+1][z];
                                league[y+1][z]=t[z];
                            }
                        }
                    }
                }
            }
        }
    }
    
    void displayleague(int noteams, int year)
    {
        int i, temp;
        printf("\nLeague Table - Season %i-%i\n", (year+2003), (year+2004));
        printf("\nPos\tTeam\t\tPld\tWon\tLost\tDrawn\tGl(for)\tGl(ag)\tPts\n");
        for (i=0;i<noteams;i++)
        {
            temp = league[i][0];
            printf("%i\t", i+1);
            printf("%s", teams[temp].name);
            printf("\t%i\t%i\t%i\t%i", league[i][1], league[i][2], league[i][3], league[i][4]);
            printf("\t%i\t%i\t%i\n", league[i][5], league[i][6], league[i][7]);
        }
        printf("\n");
        temp = league[0][7] - league[1][7];
        printf("%s", teams[(league[0][0])].name);
        teams[(league[0][0])].wins++;
        if (temp == 0)
        {
            if ((league[0][5] != league[1][5]))
                printf(" are champions on goals scored");
            else if ((league[0][6] != league[1][6]))
                printf(" are champions on goal difference");
            else printf(" are champions");
        }
        if (temp > 1)
            printf(" are champions by %i points", temp);
        if (league[0][7] == 42)
            printf(" after a perfect season");
        if (temp == 1)
            printf(" are champions by %i point", temp);
        printf(". ");
        printf("\n%s", teams[(league[7][0])].name);
        teams[(league[7][0])].rel++;
        printf(" are relegated and replaced by %s.\n", teams[8].name);
    }
    
    void swapbottom()
    {
        char *storename;
        int storequal, storewins, storerel;
        storename = teams[(league[7][0])].name;
        storequal = teams[(league[7][0])].quality;
        storewins = teams[(league[7][0])].wins;
        storerel = teams[(league[7][0])].rel;
        teams[(league[7][0])].name = teams[8].name;
        teams[(league[7][0])].quality = teams[8].quality;
        teams[(league[7][0])].wins = teams[8].wins;
        teams[(league[7][0])].rel = teams[8].rel;
        teams[8].name = storename;
        teams[8].quality = storequal;
        teams[8].wins = storewins;
        teams[8].rel = storerel;
    }
    
    void dostats()
    {
        char *tempstore, *tempstore2;
        int temp;
        tempstore2 = teams[8].name;
        printf("\ntempstore - %s\n", tempstore);
        statsfile = fopen("out.csv","w");
        for (temp = 0; temp < 9; temp++)
            {
                tempstore = teams[temp].name;
                fprintf(statsfile, "%s, %i, ", tempstore, teams[temp].wins);
                fprintf(statsfile, "%i\n", teams[temp].rel);
            }
        fclose(statsfile);
        teams[8].name = tempstore2;
        printf("\ntempstore - %s\n", tempstore);
    }

  2. #2
    Registered User JamesM's Avatar
    Join Date
    Sep 2003
    Posts
    18

    To clarify:

    With the code like this (No work around to keep the data in memory OK & no debug outputs), the element teams[8].name is corrupted.

    Code:
    void dostats()
    {
        char *tempstore, *tempstore2;
        int temp;
        statsfile = fopen("savestats.csv","w");
        fprintf(statsfile, "Team, League Wins, Relegations\n");
        for (temp = 0; temp < 9; temp++)
            {
                fprintf(statsfile, "%s, %i, ", teams[temp].name, teams[temp].wins);
                fprintf(statsfile, "%i\n", teams[temp].rel);
            }
        fclose(statsfile);
    }

  3. #3
    Registered User Sargnagel's Avatar
    Join Date
    Aug 2002
    Posts
    166
    You must either allocate memory for your team names or just initialize the array of structures as follows:
    Code:
    teamType *teams = {	{"Arsenal FC", 5, 0, 0},
    			{"Newcastle Utd", 5, 0, 0},
    			/* and so on */
    		};
    [edit]
    Maybe your function setteams() works well, because teams is a global variable. I am a little confused, because I am still suffering from a cold.
    [/edit]
    the element teams[8].name is corrupted.
    You have declared your array of structures as teamType teams[8]. There are just 8 structures at indices 0 to 7. If you want 9 teams then declare teams as follows: teamType teams[9].
    Last edited by Sargnagel; 09-29-2003 at 03:37 AM.

  4. #4
    Registered User JamesM's Avatar
    Join Date
    Sep 2003
    Posts
    18

    I feel stupid now!

    Changed:
    Code:
    typedef struct
    {
        char *name;
        int quality;
        int wins;
        int rel;
    } teamType;
    teamType teams[8];
    to:
    Code:
    typedef struct
    {
        char *name;
        int quality;
        int wins;
        int rel;
    } teamType;
    teamType teams[9];
    And it works fine!

  5. #5
    Registered User JamesM's Avatar
    Join Date
    Sep 2003
    Posts
    18

    Opening a file that's open.

    What code would I have to use to check if the csv file is already open?

    If the file is open at the moment the program crashes.

    I've tried searching the forums and the tutorials but I'm clearly not putting the right keywords in!.

    Thanks for your help.

  6. #6
    Registered User JamesM's Avatar
    Join Date
    Sep 2003
    Posts
    18

    Sorry, found it again!

    I kept looking and I found it!

    Code:
    void dostats()
    {
        int temp;
        statsfile = fopen("savestats.csv","w");
        if (!statsfile)
            printf("\n*** Warning - Could not create savestats.csv ***");
        else
        {
            fprintf(statsfile, "Team, League Wins, Relegations\n");
            for (temp = 0; temp < 9; temp++)
                {
                    fprintf(statsfile, "%s, %i, ", teams[temp].name, teams[temp].wins);
                    fprintf(statsfile, "%i\n", teams[temp].rel);
                }
            fclose(statsfile);
        }
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. literature database: help with planning
    By officedog in forum C++ Programming
    Replies: 1
    Last Post: 01-23-2009, 12:34 PM
  2. Creating a database
    By Shamino in forum Game Programming
    Replies: 19
    Last Post: 06-10-2007, 01:09 PM
  3. Replies: 10
    Last Post: 05-18-2006, 11:23 PM
  4. Developing database management software
    By jdm in forum C++ Programming
    Replies: 4
    Last Post: 06-15-2004, 04:06 PM
  5. Making a Simple Database System
    By Speedy5 in forum C++ Programming
    Replies: 1
    Last Post: 03-14-2003, 10:17 PM