You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言游戏存档异常:无法正确读写玩家数与结构体数组

存档/读档功能修复方案

核心问题分析

  • 文件打开模式错误:程序启动时直接用wb(写入二进制模式)打开文件,该模式会清空文件原有内容。选择读档(gametype=2)时,文件已被清空,自然读不到数据,导致playercount为0。
  • 读档逻辑冗余循环:读档时用while(!eof)循环重复读取playercount和玩家数据,而存档仅写入一次完整数据,循环会导致读取无效内容。
  • 语法错误:moveeffect函数定义后多了一个多余的},会导致编译失败。

修复步骤

  1. 动态切换文件打开模式
    • 新游戏(gametype=1)用wb+模式(读写二进制,清空原有内容),支持后续存档写入。
    • 读档(gametype=2)用rb模式(只读二进制),确保读取原有存档数据。
  2. 简化读档逻辑:移除多余循环,仅读取一次playercount和对应数量的玩家数据。
  3. 修复语法错误:删除moveeffect函数后的多余}。
  4. 优化存档逻辑:存档前将文件指针移到开头并截断文件,确保每次存档覆盖旧数据。

修改后的关键代码片段

文件打开部分修改

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 05:27:05