这就是我的结构:
typedef struct
{
char* name;
int played;
int win;
} Player;
这是我的代码,基本上我传递了一个结构数组,其中包括玩家名称、获胜次数和玩过的游戏次数。后面的代码所做的基本上是请求输入,问题是,一旦我将(*(players+(arraySize-1((放入文件,它就会(从同一个文件(读取,并且读取的值与之前的不同(currentPlayer.name是一个malloc,大小为MAX(:
#define N 9
#define MAX 1000
#define filename5 "tempName.bin"
#define filename6 "data.bin"
void putData(Player* players, Player currentPlayer, int arraySize)
{
FILE* fo;
FILE* fp;
fo = fopen(filename6, "ab");
fp = fopen(filename5, "wb");
if (!fp || !fo)
{
printf("error");
exit(0);
}
gets(currentPlayer.name);
(*(players + (arraySize - 1))).name = currentPlayer.name;
(*(players + (arraySize - 1))).played = 0;
(*(players + (arraySize - 1))).win = 0;
currentPlayer = (*(players + (arraySize - 1)));
fwrite(&(*(players + (arraySize - 1))), sizeof(Player), 1, fo);
fclose(fo);
FILE* fl; //and here I'm trying to read what I putted in file earlier
fl = fopen("data.bin", "rb");
fseek(stdin, 0, SEEK_CUR);//clears buffer
Player a;
a.name = malloc(MAX);
fread(&players, sizeof(Player), 1, fl);
printf("%d %d %s", a.played, a.win, a.name);
fclose(fl);
break;
fclose(fp);
}
指针无法完全保存
您必须保存它们所指向的内容,并以某种方式识别它,以便指针可以被合适的"替换;这个";文件中
然后当您发现;这个";在文件中,您首先需要在文件中找到它所指的内容,加载该文件并将其地址写入要恢复的指针变量中
请注意,在这一点上,存储在指针内的地址/数字几乎可以保证与保存前不同。但它所指向的内容是相同的,这正是你在"存储指针">
我所描述的总体思想是一个名为";持久性";对于指针的特殊情况。指针的特殊之处在于,你实际上并不想把(基本上(数字存储在里面,有必要表示"的语义;这个">
哪些细节(专有文件语法、数据库、持久性库…(需要针对您的特殊情况进行一些选择,您必须做出决定;而不是让我在这里详细地举一个例子,这些例子在某种程度上很可能与您的需求不匹配。
您不能这样做,因为指针的内容本身没有意义。
通常,这个问题可以通过用固定或可变大小的字段替换每个指针来解决;内部指针";如果文件大小和内存指针大小兼容。
typedef struct
{
char* name;
int played;
int win;
} Player;
可能变成,在文件中:
0000 4 bytes (played)
0004 4 bytes (win)
0008 2 bytes (length of name)
000A .. bytes (name)
你可以通过fread((读取前10个字节,将它们转换为类似于你的播放器的临时结构:
typedef struct
{
int32_t played;
int32_t win;
int16_t playerLength;
} FilePlayer;
此时,您将分配tmp.playerLength+1个字节,并从文件中读取tmp.playerCLength的字节,由于C字符串以零结尾,因此添加一个零,并将此内存块分配给newPlayer->名称
或者,您可以在保存文件的开头收集所有固定大小的记录,以便它们在循环中易于读取,并在末尾添加可变长度的字符串。然后,指向可变长度对象的每个固定记录项都必须成为文件本身的偏移量。
或者,您可以选择一个人工可解析文件,其中每行文本都是一个字段。这也允许使用第三方编辑器轻松检查和操作文件。在这种情况下,您可以使用辅助函数来读取int、char*等,以及:
record = malloc(sizeof Player);
if (NULL == record) {
fclose(fp);
return failure("memory error");
}
if (NULL == (record->name = readString(fp))) {
fclose(fp);
return failure("error reading name");
}
if (-1 == (record->played = readInt(fp))) {
fclose(fp);
return failure("error reading record");
}
if (-1 == (record->win = readInt(fp))) {
fclose(fp);
return failure("error reading record");
}
...