我正在制作一个基于控制台的小型RPG,以提高我的编程技巧。 我正在使用结构来存储字符数据。像他们的惠普,力量,或许库存的事情。我需要做的一件事是加载和保存字符。这意味着阅读和保存结构。
现在我只是保存并加载具有名字和姓氏的结构,并尝试正确阅读。
以下是我创建角色的代码:
void createCharacter()
{
char namebuf[20];
printf("First Name:");
if (NULL != fgets(namebuf, 20, stdin))
{
char *nlptr = strchr(namebuf, '\n');
if (nlptr) *nlptr = '\0';
}
strcpy(party[nMember].fname,namebuf);
printf("Last Name:");
if (NULL != fgets(namebuf, 20, stdin))
{
char *nlptr = strchr(namebuf, '\n');
if (nlptr) *nlptr = '\0';
}
strcpy(party[nMember].lname,namebuf);
/*Character created, now save */
saveCharacter(party[nMember]);
printf("\n\n");
loadCharacter();
}
这是saveCharacter函数:
void saveCharacter(character party)
{
FILE *fp;
fp = fopen("data","a");
fwrite(&party,sizeof(party),1,fp);
fclose(fp);
}
和loadCharacter函数
void loadCharacter()
{
FILE *fp;
character tempParty[50];
int loop = 0;
int count = 1;
int read = 2;
fp= fopen("data","r");
while(read != 0)
{
read=fread(&tempParty[loop],sizeof(tempParty[loop]),1,fp);
printf("%d. %s %s\n",count,tempParty[loop].fname,tempParty[loop].lname);
loop++;
count++;
}
fclose(fp);
}
所以程序的预期结果是我输入了一个名字和姓氏,例如'John Doe',它被附加到数据文件中。然后它被读入,可能像
1. Jane Doe
2. John Doe
程序结束。
但是,我的输出似乎在最后添加了一个空白结构。
1. Jane Doe
2. John Doe
3.
我想知道为什么会这样。请记住,我正在读取文件,直到fread返回0表示它已经命中了EOF。
谢谢:)
答案 0 :(得分:3)
更改循环:
while( fread(&tempParty[loop],sizeof(tempParty[loop]),1,fp) )
{
// other stuff
}
每当你写文件阅读代码时,问自己这个问题 - “如果我读取一个空文件会怎么样?”
答案 1 :(得分:2)
您的循环中存在算法问题,请将其更改为:
read=fread(&tempParty[loop],sizeof(tempParty[loop]),1,fp);
while(read != 0)
{
//read=fread(&tempParty[loop],sizeof(tempParty[loop]),1,fp);
printf("%d. %s %s\n",count,tempParty[loop].fname,tempParty[loop].lname);
loop++;
count++;
read=fread(&tempParty[loop],sizeof(tempParty[loop]),1,fp);
}
有一些方法可以摆脱双重恐惧,但首先让它发挥作用并确保你理解流程。
答案 2 :(得分:1)
下面:
read=fread(&tempParty[loop],sizeof(tempParty[loop]),1,fp);
printf("%d. %s %s\n",count,tempParty[loop].fname,tempParty[loop].lname);
您没有检查读取是否成功(fread()
的返回值)。
答案 3 :(得分:1)
while( 1==fread(&tempParty[loop],sizeof*tempParty,1,fp) )
{
/* do anything */
}
是正确的方法。
使用fopen("data","rb")
而不是fopen("data","r")
,相当于fopen("data","rt")
答案 4 :(得分:0)
你已经得到了你当前问题的答案,但值得指出的是盲目地写作和阅读整个结构并不是一个好的计划。
结构布局可以并且确实会发生变化,具体取决于您使用的编译器,该编译器的版本以及使用的确切编译器标志。此处的任何更改都将破坏您阅读使用其他版本保存的文件的能力。
如果您有支持多个平台的野心,那么像endianness这样的问题也会发挥作用。
然后如果你在以后的版本中向你的结构添加元素会发生什么......
为了提高稳健性,您需要考虑独立于代码定义文件格式,并使用保存和加载功能处理此格式的序列化和反序列化。