cstructfile-iofwritefread

C- Trying to store an integer and array of structs into a binary file


I'm attempting to make a game, where I have structs for each player, and store those player structs in an array. Now I'm trying to add a save/load feature to the game, saving the number of players and the struct for each player, but for some reason I can't figure out how to get the data to store correctly. I'm using a binary file, and try to fread the whole array into the variable, so the game can go on, but it either doesn't load the file at all, or the game reads the playercount as 0 and just ends. Any suggestions? Thanks for the help. Sorry for the long code.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef struct {
    int active;
    int team;
    int number;
    int health;
    char type;
    int speed;
    int stunned;
    int move1effect;
    int move2effect;
    int move3effect;
    int move4effect;
    int move1dmg;
    int move2dmg;
    int move3dmg;
    int move4dmg;
    int move1hitchance;
    int move2hitchance;
    int move3hitchance;
    int move4hitchance;
    char move1name[50];
    char move2name[50];
    char move3name[50];
    char move4name[50];
    char move1type;
    char move2type;
    char move3type;
    char move4type;
} playerdata;

playerdata addPlayer(int selection, int team, int number){

}

void moveprompt(playerdata* p){

}

void moveeffect(playerdata* cP, int target, playerdata* pptr[], int damagemultiplier, int miss, int movehitchance, int movedmg, char movename[], int moveeffect){

}

}
void maketurn(playerdata* cP, int currentP, int sel, int target, playerdata* pptr[]){

}

void printplayerstatus(playerdata* pptr[], int playercount){
       
}


int main(){
int c= 1;
srand(time(NULL));
FILE* file = fopen("file.bin", "wb");
if (file == NULL){
printf("Error opening file");
return 1;
}
int playercount=0;
int numofplayers=0;
int numofcpus=0;

int gametype;
playerdata* ptr[50];
playerdata p[50];
printf(
    "Start new game or load previous save?\n"
    "1: Start new game\n"
    "2: Load previous save\n"
);
scanf("%d",&gametype);

if(gametype == 1){
int selection = 0, team = 0;
 
    printf("How many player characters?(1-5)\n");
    scanf("%d", &numofplayers);

    printf("How many computer players?(1-5)\n");
    scanf("%d", &numofcpus);
    
    playercount = numofplayers + numofcpus;
    //playerdata p[playercount];
    for(int i = 0; i<playercount; i++){
        ptr[i] = &p[i];
    }
    for(int i = 0; i<numofplayers; i++){
    printf("Player %d: Select a Character\n"
            "1: Charmander (Fire type, 2x Damage to Bulbasaur)\n"
            "2: Bulbasaur (Grass type, 2x Damage to Squirtle)\n"
            "3: Squirtle (Water Type, 2x Damage to Charmander)\n", i+1
            );
    scanf("%d", &selection);
    team = 1;
     p[i] = addPlayer(selection, team, i+1);
    }
   
    for(int i = 0; i<numofcpus; i++){
    selection = 0, team = 0;

    int r = rand() % 3;
    selection = (r+1);
    team = 2; 
     p[i+numofplayers] = addPlayer(selection, team, (i+1)+numofplayers);
    }
}

if(gametype == 2){
    int eof=0;
    while(!eof){
        fread(&playercount, sizeof(int),1,file);
        //playerdata p[playercount];
        printf("Playercount: %d\n",playercount);
        
        for(int i = 0; i<playercount; i++){
            ptr[i]=&p[i];
        }
        fread(p, sizeof(playerdata),playercount,file);
        eof=feof(file);
    }
}

playerdata* pptr[playercount];
    for(int i = 0; i<playercount; i++){
        pptr[i] = ptr[i];
    }

playerdata* turnptr[playercount];

for(int i = 0; i<playercount; i++){
turnptr[i]= pptr[i];
}


while(c==1){//main game loop as long as 1 team is alive
int team1Alive = 0;
int team2Alive = 0;
for(int i = 0; i<playercount; i++){
    if(turnptr[i]->active == 1){
        if(turnptr[i]->health > 0){
             if(turnptr[i]->team == 1){
                team1Alive = 1;
            }else if (turnptr[i]->team==2){
                team2Alive= 1;
            }
            printplayerstatus(pptr, playercount);  
            
            if(turnptr[i]->stunned != 1){
                    
                int sel = 0;
                int target = 0;
                printf("\nPLAYER %d'S TURN:\n",turnptr[i]->number);
                moveprompt(turnptr[i]);
                if(turnptr[i]->team == 1){
                    
                    scanf("%d", &sel);
                   if(sel==5){
                    printf("saving...\n");
                    fwrite(&playercount, sizeof(int), 1, file);
                    for(int i = 0; i<playercount; i++){
                        fwrite(pptr[i],sizeof(playerdata),1,file);
                    }
                    
                    printf("Wrote to file successfully.\n");
                    return 0;
                   }
                    if(sel!=4){
                        printf("Who to attack? (Enter player number) \n");
                        scanf("%d",&target);
                    }
                }else if (turnptr[i]->team == 2){
                    sel = ((rand() % 4)+1);
                    target = ((rand() % 2)+1);
                }

            maketurn(turnptr[i],turnptr[i]->number, sel, target, pptr);
        
            }else if(turnptr[i]->stunned == 1){
                printf("Player %d is stunned and cannot move!\n",turnptr[i]->number);
                turnptr[i]->stunned = 0;
            }
        }//end if hp>0 loop
    }
}

     if(team1Alive != 1){
        printf("Team 2 Wins!\n");
        c=5;
    }
    if(team2Alive != 1){
        printf("Team 1 Wins!\n");
        c=5;
    }
    
}

fclose(file);
return 0;
}


I've attempted to store each struct individually and read each individually, and debug printing the playercount on load, but each time the playercount reads as 0, so I'm wondering if it's not saving correctly or maybe if it's saving over the integer with the struct.


Solution

  • You open the file at the start of the program like this:

    FILE* file = fopen("file.bin", "wb");
    

    Note that “w” (and therefore “wb” with the option for binary) as the mode parameter will destroy the file contents if it already exists, so you have nothing to be able to load.

    https://en.cppreference.com/w/c/io/fopen