【发布时间】:2020-01-07 20:52:22
【问题描述】:
我在使用 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 上检查了很多问题,但我不知道如何使它正确 - 对我来说最重要的是 - 易于理解和可读(我可能可以在一个 fscanf 中完成所有操作,其中包含整个 .txt 文件和变量为 %d,但它看起来很乱)
我也尝试在每个 fscanf 的末尾给出 '\n' 但它会带来库错误
还有我的savegame.txt 文件:
beeseed= 8
car 0 pos x= 952 y=427
car 0 speed= 9
obstacle 0 pos x= 1028 y=217
obstacle 0 speed= 10
frogend 0= 0
car 1 pos x= 647 y=392
car 1 speed= 8
obstacle 1 pos x= 1131 y=182
obstacle 1 speed= 5
frogend 1= 1
car 2 pos x= 604 y=357
car 2 speed= 5
obstacle 2 pos x= -71 y=147
obstacle 2 speed= 5
frogend 2= 0
car 3 pos x= 437 y=322
car 3 speed= 6
obstacle 3 pos x= 320 y=112
obstacle 3 speed= 7
frogend 3= 0
car 4 pos x= 142 y=287
car 4 speed= 5
obstacle 4 pos x= 7 y=77
obstacle 4 speed= 7
frogend 4= 0
health= 5
worldTime= 4.892000
frog pos x= 320 y=462
lost frog pos x= 376 y= 182 rand= 188
score bee= 200 score end= 476
score flag= 0 score frog= 0
score pos= 0 score total= 120
问题可能是我的结构包含布尔值save.frogend[i] 是布尔形式并且需要 %d(也是 1/0)?
typedef struct {
int x;
int y;
}pos;
typedef struct {
short int pos;
short int end;
short int frog;
short int bee;
short int total;
short int flag;
} score;
typedef struct {
bool frogend[5];
score score;
pos frog;
struct {
pos pos;
int rand;
}lostfrog;
struct {
pos pos;
int rand;
}obstacles[5];
struct {
pos pos;
int rand;
}cars[5];
short int beeseed;
double worldTime;
int health;
}saved;
【问题讨论】:
-
我猜
%d也可能存在问题-您的结构成员之一可能是long或bool或char或unsigned int,而不是int。需要把saved的定义贴出来让别人查。 -
你忘了pos。
-
你有:
fscanf(fptr, "car %d pos x= %d y=%d", i, &save->cars[i].pos.x, &save->cars[i].pos.y);— 你需要将&i传递给fscanf()(或者,更确切地说,是i以外的某个整数变量),或者使用%*d禁止赋值。 -
Lidbey,为什么代码不检查
fscanf()的返回值? -
"试图在每个 fscanf 结束时给出 '\n'" 不是一个坏主意。然而,启用警告的优秀编译器会抱怨
fscanf(fptr, "car %d pos x= %d y=%d", i, &save->cars[i].pos.x, &save->cars[i].pos.y);。通过启用所有警告来节省时间并提高调试速度。