C fprintf和fscanf保存游戏状态

问题描述 投票:-1回答:1

我在使用fscanf和fprintf时遇到问题,我已经将游戏状态保存到文件中,然后尝试从同一文件中加载它(下次我打开程序时)

我有功能:

bool savegame(saved save) {
    FILE* fptr;
    fptr = fopen("savegame.txt", "w+");
    if (fptr == NULL)
        return 0;
    fprintf(fptr, "beeseed= %d\n", save.beeseed);
    for (int i = 0; i < 5; i++)
    {
        fprintf(fptr, "car %d pos x= %d y=%d\n", i, save.cars[i].pos.x, save.cars[i].pos.y);
        fprintf(fptr, "car %d speed= %d\n", i, save.cars[i].rand);
        fprintf(fptr, "obstacle %d pos x= %d y=%d\n", i, save.obstacles[i].pos.x, save.obstacles[i].pos.y);
        fprintf(fptr, "obstacle %d speed= %d\n", i, save.obstacles[i].rand);
        fprintf(fptr, "frogend %d= %d\n", i, save.frogend[i]);
    }
    fprintf(fptr, "health= %d\n", save.health);
    fprintf(fptr, "worldTime= %f\n", save.worldTime);
    fprintf(fptr, "frog pos x= %d y=%d\n", save.frog.x, save.frog.y);
    fprintf(fptr, "lost frog pos x= %d y= %d rand= %d\n", save.lostfrog.pos.x, save.lostfrog.pos.y, save.lostfrog.rand);
    fprintf(fptr, "score bee= %d score end= %d\n", save.score.bee, save.score.end);
    fprintf(fptr, "score flag= %d score frog= %d\n", save.score.flag, save.score.frog);
    fprintf(fptr, "score pos= %d score total= %d\n", save.score.pos, save.score.total);
    fclose(fptr);
    return 1;
}

而且这很好用,我的意思是-我的文件正确填充了值。现在,我尝试扫描此文件:

bool loadgame(saved* save) {
    FILE* fptr;
    fptr = fopen("savegame.txt", "r");
    if (fptr == NULL)
        return 0;
    fscanf(fptr, "beeseed= %d", &save->beeseed);
    for (int i = 0; i < 5; i++)
    {

    fscanf(fptr, "car %d pos x= %d y=%d", i, &save->cars[i].pos.x, &save->cars[i].pos.y);
    fscanf(fptr, "car %d speed= %d", i, &save->cars[i].rand);
    fscanf(fptr, "obstacle %d pos x= %d y=%d", i, &save->obstacles[i].pos.x, &save->obstacles[i].pos.y);
    fscanf(fptr, "obstacle %d speed= %d", i, &save->obstacles[i].rand);
    fscanf(fptr, "frogend %d= %d", i, &save->frogend[i]);
    }
    fscanf(fptr, "health= %d", &save->health);
    fscanf(fptr, "worldTime= %lf", &save->worldTime);
    fscanf(fptr, "frog pos x= %d y=%d", &save->frog.x, &save->frog.y);
    fscanf(fptr, "lost frog pos x= %d y= %d rand= %d", &save->lostfrog.pos.x, &save->lostfrog.pos.y, &save->lostfrog.rand);
    fscanf(fptr, "score bee= %d score end= %d", &save->score.bee, &save->score.end);
    fscanf(fptr, "score flag= %d score frog= %d", &save->score.flag, &save->score.frog);
    fscanf(fptr, "score pos= %d score total= %d", &save->score.pos, &save->score.total);
    fclose(fptr);
    return 1;
}

并且仅适用于文件的第一行(beeseed = 3),其他行根本不起作用

我知道我可能不太了解fscanf,但是我在google上检查了很多问题,我也不知道如何使其正确-而且对我来说最重要-易于理解和可读(我可能可以在一个装满整个.txt文件和变量为%d的fscanf中完成所有操作,但是看起来太混乱了]

我也曾尝试在每个fscanf的末尾加上'\ n',但这会带来库错误

c scanf
1个回答
0
投票

您不会跳过fscanf()格式字符串中的换行符。因此,第二个fscanf()将失败,因为它希望在最后一个car之后立即找到单词y=%d,但是它们之间有换行符。

在每个格式字符串的开头放置一个空格。这将使其跳过任何领先的空格。

bool loadgame(saved* save) {
    FILE* fptr;
    fptr = fopen("savegame.txt", "r");
    if (fptr == NULL)
        return 0;
    fscanf(fptr, "beeseed= %d", &save->beeseed);
    for (int i = 0; i < 5; i++)
    {

        fscanf(fptr, " car %d pos x= %d y=%d", i, &save->cars[i].pos.x, &save->cars[i].pos.y);
        fscanf(fptr, " car %d speed= %d", i, &save->cars[i].rand);
        fscanf(fptr, " obstacle %d pos x= %d y=%d", i, &save->obstacles[i].pos.x, &save->obstacles[i].pos.y);
        fscanf(fptr, " obstacle %d speed= %d", i, &save->obstacles[i].rand);
        fscanf(fptr, " frogend %d= %d", i, &save->frogend[i]);
    }
    fscanf(fptr, " health= %d", &save->health);
    fscanf(fptr, " worldTime= %lf", &save->worldTime);
    fscanf(fptr, " frog pos x= %d y=%d", &save->frog.x, &save->frog.y);
    fscanf(fptr, " lost frog pos x= %d y= %d rand= %d", &save->lostfrog.pos.x, &save->lostfrog.pos.y, &save->lostfrog.rand);
    fscanf(fptr, " score bee= %d score end= %d", &save->score.bee, &save->score.end);
    fscanf(fptr, " score flag= %d score frog= %d", &save->score.flag, &save->score.frog);
    fscanf(fptr, " score pos= %d score total= %d", &save->score.pos, &save->score.total);
    fclose(fptr);
    return 1;
}

另一种选择是使用fgets()读取每一行,然后使用sscanf()从中提取值。

© www.soinside.com 2019 - 2024. All rights reserved.