前言
- 在简易通讯录版本为基础,修改为可动态增长的通讯录内存大小,以及将录入的通讯录内容保存在本地文件中,并在下一次录入前导入到本地内存
动态控制通讯录大小
- 修改通讯录的结构体
sz 记录通讯录中信息个数,初始为0
capacity 记录通讯录内存大小,初始为0
typedef struct Contact{
PeoInfo* data;
int sz;
int capacity;
}Contact;
- 新增检查通讯内存函数
在每次导入或者新增信息前,检查通讯里剩余内存,内存不足则动态增长
void Check_Capacity(Contact* pc){
assert(pc);
if(pc->sz == pc->capacity){
PeoInfo* tmp = (PeoInfo*)realloc(pc->data, (pc->capacity+3) * sizeof(PeoInfo));
if(tmp != NULL){
pc->data = tmp;
pc->capacity += 3;
printf("增容成功\n");
}
else{
perror("Check_Capacity::realloc");
return;
}
}
}
- 新增销毁通讯录函数
void DestoryContact(Contact* pc) {
free(pc->data);
pc->sz = 0;
pc->capacity = 0;
pc->data = NULL;
printf("销毁成功\n");
}
在文件中储存和导入通讯录信息
- 新增储存函数
将通讯录数据以二进制形式储存到文件 Contact.dat
void SaveContact(const Contact* pc){
FILE* pf = fopen("Contact.dat","wb");
if (NULL == pf) {
perror("SaveContact::fopen");
return;
}
for (int i = 0; i < pc->sz; i++) {
fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);
}
printf("保存通讯录成功\n");
fclose(pf);
pf = NULL;
}
- 新增导入函数
从文件 Contact.dat 以二进制形式导入通讯录信息到内存中
void LoadContact(Contact* pc) {
// 打开文件
FILE* pf = fopen("contact.dat","rb");
if(NULL == pf){
perror("LoadContact::fopen");
return;
}
else{
// 暂存读取的数据
PeoInfo tmp = { 0 };
// 读文件
while(fread(&tmp, sizeof(PeoInfo), 1, pf)){
// 导入前也得检查内存大小
Check_Capacity(pc);
pc->data[pc->size++] = tmp;
}
printf("通讯录导入成功\n");
}
PrintContact(pc);
// 关闭文件
fclose(pf);
pf = NULL;
}
- 修改初始化函数
void InitContact(Contact* pc){
assert(pc);
pc->sz = 0;
pc->capacity = 3;
pc->data = (PeoInfo*)malloc(sizeof(PeoInfo) * pc->capacity);
if (NULL == pc->data) {
perror("InitContact::malloc");
return;
}
//初始化通讯录
memset(pc->data, 0, pc->capacity * sizeof(pc->data));
// 导入已有通讯录
LoadContact(pc);
}
运行截图
- 首次运行
- 第二次运行