繁体   English   中英

为什么我的程序会读取额外的结构?

[英]Why does my program read an extra structure?

我正在制作一个基于控制台的小型rpg,以提高我的编程技能。 我正在使用结构来存储字符数据。 诸如HP,Strength之类的东西,也许还有库存。 我需要做的关键事情之一就是加载和保存字符。 这意味着读取并保存结构。

现在,我只是保存和加载具有名字和姓氏的结构,并尝试正确读取它。

这是我创建角色的代码:

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。

谢谢 :)

改变你的循环:

while( fread(&tempParty[loop],sizeof(tempParty[loop]),1,fp) )
{
    // other stuff
}

每当您编写文件读取代码时,都会问自己一个问题-“如果我读取一个空文件会怎样?”

您的循环中遇到算法问题,请将其更改为:

 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);
 }

有多种方法可以消除双重担忧,但首先请使其正常工作并确保您了解流程。

这里:

    read=fread(&tempParty[loop],sizeof(tempParty[loop]),1,fp);
    printf("%d. %s %s\n",count,tempParty[loop].fname,tempParty[loop].lname);

您没有在检查读取是否成功( fread()的返回值)。

while( 1==fread(&tempParty[loop],sizeof*tempParty,1,fp) )
{
/* do anything */
}

是正确的方法。

使用fopen("data","rb")而不是fopen("data","r")等效于fopen("data","rt")

您已经得到了您眼前一个问题的答案,但值得指出的是,盲目写作和阅读整个结构并不是一个好的计划。

结构布局可以而且确实会根据您使用的编译器,该编译器的版本甚至使用的确切编译器标志而发生变化。 此处的任何更改都会破坏您读取使用其他版本保存的文件的能力。

如果您有支持多个平台的抱负,那么字节序之类的问题也将发挥作用。

如果在以后的版本中向结构中添加元素,则会发生什么情况……

为了增强鲁棒性,您需要考虑独立于代码定义文件格式,并让保存和加载功能处理该格式的序列化和反序列化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM