大家好我是沐曦希💕
1.前言
即便动态版本的通讯录能更改通讯录内存的大小,但是一样具有一定的缺陷,便是不能在程序关闭的时候,对通讯录进行保存。那么现在我们可以根据前面所学到文件操作和动态版本的通讯录进行优化,把通讯录保存在文件中。
2.文件功能实现
2.1 保存通讯录的信息
在退出程序时候,应该进行保存通讯录的信息的操作,那么就需要我们写一个函数来实现这个功能
void SaveContact(const struct Contact* pc)
{
assert(pc);
FILE* pfwrite = fopen("contact.txt", "wb");
if (pfwrite == NULL)
{
perror("SaveContact");
return;
}
//写文件二进制
int i = 0;
for (i = 0; i < pc->count; i++)
{
fwrite(pc->data+i, sizeof(PeoIoFo), 1, pfwrite);
}
fclose(pfwrite);
pfwrite = NULL;
}
通过二进制形式写入,可以一定程度减少内存的占用。
2.2 初始化通讯录
void CheckCapacity(Contact* pc)
{
if (pc->count == pc->capacity)
{
PeoIoFo* ptr = (PeoIoFo*)realloc(pc->data, (pc->capacity + 2) * sizeof(PeoIoFo));
if (ptr == NULL)
{
printf("AddContact::%s\n", strerror(errno));
return;
}
else
{
pc->data = ptr;
pc->capacity += 2;
printf("增容成功\n");
}
}
}
void LodeContact(struct Contact* pc)
{
FILE* pfread = fopen("Contact.txt", "rb");
if (pfread == NULL)
{
perror("LodeContact");
return;
}
PeoIoFo tmp = {
0 };
while (fread(&tmp, sizeof(PeoIoFo), 1, pfread))
{
CheckCapacity(pc);
pc->data[pc->count] = tmp;
pc->count++;
}
fclose(pfread);
pfread = NULL;
}
int InitContact(struct Contact* pc)
{
assert(pc);
pc->count = 0;
pc->data = (PeoIoFo*)calloc(3, sizeof(PeoIoFo));
if (pc->data == NULL)
{
printf("InitContact:%s\n", strerror(errno));
return 1;
}
pc->capacity = 3;
//加载文件的信息到通讯录中
LodeContact(pc);
return 0;
}
在初始化通讯录后,应该将文件中保存的通讯录信息进行复制到现在的通讯录当中,那么就需要一个函数来实现。
LodeContact中while循环通过判断fread返回值是否为0来确定通讯录的信息是否被读取完。
当然也要检测当前通讯录是否有足够大的空间来存储文件中的通讯录的信息,不够则用realloc函数来增大空间。
3.完整代码
contact.h
#pragma once
#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<errno.h>
#include<stdlib.h>
typedef struct PeoIoFo
{
char name[20];
int age;
char sex[10];
char tele[12];
char addr[20];
}PeoIoFo;
typedef struct Contact
{
struct PeoIoFo* data;
int count;
//当前通讯录的容量
int capacity;
}Contact;
//初始化通讯录
int InitContact(struct Contact* pc);
//添加联系人信息
void AddContact(struct Contact* pc);
//打印联系人信息
void ShowContact(const struct Contact* pc);
//删除联系人信息
void DelContact(struct Contact* pc);
//查找联系人
void SearchContact(const struct Contact* pc);
//修改联系人信息
void ModifyContact(struct Contact* pc);
//排序联系人信息
void SortContact(struct Contact* pc);
//清空所有联系人
void AlldelContact(struct Contact* pc);
//销毁所有联系人信息
void DestroyContact(struct Contact* pc);
//存储联系人信息
void SaveContact(const struct Contact* pc);
//加载文件的联系人信息
void