C语言 错误与结构保存和加载功能


#include <stdio.h>
#include <stdlib.h>
struct birdhome{
int area;
int heightcm;
int feederquantity;
char hasNest[6];
};
struct bird{
char isRinged[6];
char nameSpecies[50];
int birdAgeMonths;
struct BirdHome *hom;
char gender[7];
};
int save(char * filename, struct bird *st, int n);
int load(char * filename);
int main(void)
{
char * filename = "birds.dat";
struct bird birds[] = { "True","sparrow",3,10,20,2,"False","Male","False","crane",24,50,100,6,"True","Female","False","False","griffin",10,100,80,1,"False","Male" };
int n = sizeof(struct bird) / sizeof(birds[0]);
save(filename, birds, n);
load(filename);
return 0;
}
int save(char * filename, struct bird * st, int n)
{
FILE * fp;
char *c;

int size = n * sizeof(struct bird);
if ((fp = fopen(filename, "wb")) == NULL)
{
perror("Error occured while opening file");
return 1;
}

c = (char *)&n;
for (int i = 0; i<sizeof(int); i++)
{
putc(*c++, fp);
}

c = (char *)st;
for (int i = 0; i < size; i++)
{
putc(*c, fp);
c++;
}
fclose(fp);
return 0;
}
int load(char * filename){
FILE * fp;
char *c;
int m = sizeof(int);
int n, i;

int *pti = (int *)malloc(m);
if ((fp = fopen(filename, "r")) == NULL)
{
perror("Error occured while opening file");
return 1;
}

c = (char *)pti;
while (m>0)
{
i = getc(fp);
if (i == EOF) break;
*c = i;
c++;
m--;
}

n = *pti;

struct bird * ptr = (struct bird *) malloc(n * sizeof(struct bird));
c = (char *)ptr;

while ((i= getc(fp))!=EOF)
{
*c = i;
c++;
}

printf("n%d birds in the file storednn", n);
for (int k = 0; k<n; k++)
{
printf("%-10d %-6s %-50s %-24d %-100d %-100d %-10d %-10s %-10s  n", k + 1, (ptr + k)->isRinged, (ptr + k)->nameSpecies,(ptr + k)->birdAgeMonths,(ptr + k)->hom.area,(ptr + k)->hom.heightcm,(ptr + k)->hom.feederquantity,(ptr + k)->hom.hasNest,(ptr + k)->gender);
}

程序理论上是可以运行的。问题在于load函数中的printf
错误提示struct Birdhome中所有的结构类型都是a我应该使用->而不是.

但是当我这样做的时候,它说我应该把.改成->

问题是bird.hom是一个指针。保存指向文件的指针并不是一件有用的事情,因为内存地址会随着进程的不同而变化。它也没有保存BirdHome结构的内容。并且birds的初始化不起作用,因为不能将间接结构体的成员初始化为主结构体的一部分。

你应该将它声明为一个嵌入式结构体,而不是指针。

struct bird{
char isRinged[6];
char nameSpecies[50];
int birdAgeMonths;
struct BirdHome hom;
char gender[7];
};

如果你想要一个动态大小的home数组,或者你想让多个bird引用同一个BirdHome结构体,那么将它声明为一个指针是很有用的。如果这是您真正需要的,则需要重新设计save和load函数,以便它们解引用指针并保存指针指向的内容。如果你有一个动态大小的BirdHome数组,你需要在bird中包含数组的大小。

代码中的其他错误:

birds的初始化列表中有一个额外的"False"。应该是:

struct bird birds[] = { "True","sparrow",3,10,20,2,"False","Male","False","crane",24,50,100,6,"True","Female","False","griffin",10,100,80,1,"False","Male" };

你计算的n不正确。应该是:

int n = sizeof(birds) / sizeof(birds[0]);

最新更新