动态版本通讯录改造
静态版本通讯录链接
链接: link
动态版本通讯录代码链接
链接: link
静态版本的缺陷:
1:通讯录大小固定无法增容,改造目标:使用动态内存管理,让通讯录大小可以动态变化。
创建动态管理版本的结构体
typedef struct PeoInfo
{
char name[MAX_NAME];
int age;
char sex[MAX_SEX];
char tele[MAX_TELE];
char addr[MAX_TELE];
}PeoInfo;//创建结构体保存联系人信息
typedef struct Contact
{
PeoInfo* date;//创建结构体指针,使用malloc动态管理结构体大小。
int capacity;//记录当前通讯录容量。
int sz;//记录当前存放了多少联系人。
}Contact;
//改造通讯录初始大小可以存放3人信息,存放联系人超过通讯录容量时,增容2人。
初始化通讯录
void InitContact(Contact* pc)
{
pc->date = malloc(DEFAULT_SZ * sizeof(PeoInfo));//使用malloc为通讯录开辟空间。
if (pc->date == NULL)
{
printf("初始化通讯录失败:%s\n", strerror(errno));
}
pc->sz = 0;
pc->capacity = DEFAULT_SZ;
LoadContact(pc);//将存放在文件中的联系人信息加载到内存中。
return;
}
当空间不足时对通讯录增容
void CheckCapacity(Contact* pc)
{
if (pc->sz == pc->capacity)//当容量等于存放联系人个数时,就需要对通讯录进行增容。
{
PeoInfo* ptr = realloc(pc->date, (pc->capacity + INT_SZ) * sizeof(PeoInfo));//使用realloc调整通讯录大小。
if (ptr == NULL)
{
printf("扩容失败:%s\n", strerror(errno));
return;
}
pc->date = ptr;
pc->capacity += INT_SZ;
printf("扩容成功:%d\n", pc->capacity);
}
}//检查当前通讯录是否需要增容
使用动态申请的空间要进行释放,否则会出现内存泄漏
void DestroyContact(Contact* pc)
{
free(pc->date);
pc->date = NULL;
pc->sz = 0;
pc->capacity = 0;
return;
}
2:通讯录退出后信息无法保存,改造目标:将信息存放在文件中,程序开始时加载信息,退出时保存信息。
保存联系人信息
int SaveContact(Contact* pc)
{
FILE* pf = fopen("contact.dat", "wb");//以二进制形式将信息写入文件
if (pf == NULL)
{
perror("fopen");
return 1;
}
int i = 0;
for (i = 0; i < pc->sz; i++)
{
fwrite(pc->date + i, sizeof(struct PeoInfo), 1, pf);//每次写入一个联系人信息
}
fclose(pf);
pf = NULL;
printf("保存成功\n");
return 0;
}
加载联系人信息
int LoadContact(Contact* pc)
{
FILE* pf = fopen("Contact.dat", "rb");
if (pf == NULL)
{
perror("fopen");
return 1;
}
PeoInfo tmp = { 0 };
while (fread(&tmp, sizeof(PeoInfo), 1, pf))//fread函数返回值为当前读取到的信息数
{
CheckCapacity(pc);//写入信息时,容量不足就进行增容。
pc->date[pc->sz] = tmp;
pc->sz++;//更新以存放联系人个数
}
fclose(pf);
pf = NULL;
return 0;
}