C语言游戏存档异常:无法正确读写玩家数与结构体数组
存档/读档功能修复方案
核心问题分析
- 文件打开模式错误:程序启动时直接用
wb(写入二进制模式)打开文件,该模式会清空文件原有内容。选择读档(gametype=2)时,文件已被清空,自然读不到数据,导致playercount为0。 - 读档逻辑冗余循环:读档时用
while(!eof)循环重复读取playercount和玩家数据,而存档仅写入一次完整数据,循环会导致读取无效内容。 - 语法错误:
moveeffect函数定义后多了一个多余的},会导致编译失败。
修复步骤
- 动态切换文件打开模式
- 新游戏(gametype=1)用
wb+模式(读写二进制,清空原有内容),支持后续存档写入。 - 读档(gametype=2)用
rb模式(只读二进制),确保读取原有存档数据。
- 新游戏(gametype=1)用
- 简化读档逻辑:移除多余循环,仅读取一次
playercount和对应数量的玩家数据。 - 修复语法错误:删除
moveeffect函数后的多余}。 - 优化存档逻辑:存档前将文件指针移到开头并截断文件,确保每次存档覆盖旧数据。
修改后的关键代码片段
文件打开部分修改
int main(){ int c= 1; srand(time(NULL)); FILE* file = NULL; 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){ file = fopen("file.bin", "wb+"); if (file == NULL){ printf("Error opening file"); return 1; } // 原有新游戏逻辑... } else if(gametype == 2){ file = fopen("file.bin", "rb"); if (file == NULL){ printf("Error opening save file"); return 1; } // 修改后的读档逻辑... }
读档逻辑修改
if(gametype == 2){ // 读取玩家数量 if(fread(&playercount, sizeof(int), 1, file) != 1){ printf("Failed to read player count\n"); fclose(file); return 1; } printf("Playercount: %d\n",playercount); // 校验玩家数量合法性 if(playercount <=0 || playercount >50){ printf("Invalid player count in save file\n"); fclose(file); return 1; } for(int i = 0; i<playercount; i++){ ptr[i]=&p[i]; } // 读取所有玩家数据 if(fread(p, sizeof(playerdata), playercount, file) != playercount){ printf("Failed to read player data\n"); fclose(file); return 1; } }
存档逻辑优化
if(sel==5){ printf("saving...\n"); // 移到文件开头并截断,覆盖旧存档 fseek(file, 0, SEEK_SET); ftruncate(fileno(file), 0); if(fwrite(&playercount, sizeof(int), 1, file) !=1){ printf("Failed to write player count\n"); fclose(file); return 1; } for(int i = 0; i<playercount; i++){ if(fwrite(pptr[i],sizeof(playerdata),1,file) !=1){ printf("Failed to write player %d data\n", i+1); fclose(file); return 1; } } printf("Wrote to file successfully.\n"); fclose(file); return 0; }
语法错误修复
删除moveeffect函数后的多余}:
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[]){ }
内容的提问来源于stack exchange,提问作者catodd
相关产品推荐
相关产品推荐

