之前我们了解过静态通讯录的实现,但静态通讯录一次性创造了大量的内存,对一些用户来说未免有些浪费。
今天我们在静态通讯录的基础上简单了解一下如何实现动态通讯录,话不多说直接上代码。
test.c
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include"contact.h"
void menu()
{
printf("****************************************************\n");
printf("***** 1.添加联系人 2.删除联系人 *******\n");
printf("***** 3.查找联系人 4.修改联系人 *******\n");
printf("***** 5.展示联系人 6.排序联系人 *******\n");
printf("***** 7.清空联系人 0.退出 *******\n");
printf("****************************************************\n");
}
enum option
{
exit,
add,
del,
search,
modify,
show,
sort,
clear
};
int main()
{
int input = 0;
struct contact con;//创建一个通讯录
InitContact(&con);//初始化通讯录
do
{
menu();//打印菜单
printf("请选择》》");
scanf("%d", &input);
switch (input)
{
case exit:
DestroyContact(&con); //退出时销毁
printf("退出\n");
break;
case add:
tianjia(&con);
break;
case del:
shanchu(&con);
break;
case search:
chazhao(&con);
break;
case modify:
xiugai(&con);
break;
case show:
dayin(&con);
break;
case sort:
paixu(&con);
break;
case clear:
qingkong(&con);
break;
default:
printf("选择错误\n");
break;
}
} while (input);
return 0;
}
contact.h
#pragma once
#define max 1000
#define name_max 20
#define sex_max 5
#define tel_max 15
#define ads_max 30
#include<stdio.h>
#include<assert.h>
struct pepinfo//描述一个人的信息
{
char name[name_max];//姓名
char sex[sex_max];//性别
int age;//年龄
char tel[tel_max];//电话号码
char ads[ads_max];//家庭住址
};
typedef struct contact
{
struct pepinfo* data;
int num;//有效元素的个数
int capacity;//容量
}contact;
contact.c
#define _CRT_SECURE_NO_WARNINGS
#include"contact.h"
#include<stdio.h>
#define DEFAULT_SZ 3
//先对函数进行声明
void InitContact(struct contact* con);
void tianjia(struct contact* con);
void shanchu(struct contact* con);
void chazhao(const struct contact* con);
void dayin(struct contact* con);
void xiugai(struct contact* con);
void paixu(struct contact* con);
void CheckCapacity(contact* con);
//添加联系人
void tianjia(struct contact *con)
{
CheckCapacity(con);//先检查联系人是否已满
if (con->num == max)
{
printf("\n通讯录已满,添加失败\n");
}
else
{
printf("\n请输入联系人姓名》");
scanf("%s", con->data[con->num].name);
printf("\n请输入联系人性别》");
scanf("%s", con->data[con->num].sex);
printf("\n请输入联系人年龄》");
scanf("%d", &con->data[con->num].age);//age是变量 需要取地址&
printf("\n请输入联系人电话》");
scanf("%s", con->data[con->num].tel);
printf("\n请输入联系人住址》");
scanf("%s", con->data[con->num].ads);
con->num++;
printf("\n添加成功\n");
}
}
//删除联系人
void shanchu(struct contact* con)
{
int n = 0;
printf("\n请输入要删除联系人的序列号");
scanf("%d", &n);
if (n<1 || n>con->num)
{
printf("不存在的序列号,删除失败\n");
}
else
{
for (int i = 0; i <= con->num - n; i++)
{
*(con->data[n-1 + i].name) = *(con->data[n + i ].name);
*(con->data[n-1 + i].sex) = *(con->data[n + i ].sex);
con->data[n-1 + i].age = con->data[n + i ].age;
*(con->data[n-1 + i].tel) = *(con->data[n + i ].tel);
*(con->data[n-1 + i].ads) = *(con->data[n + i ].ads);
}
con->num--;//不要忘了把联系人数量减1
printf("删除成功\n");
}
}
//查找联系人
void chazhao(const struct contact*con)
{
printf("请输入需要查找的序号>");
int n = 0;
scanf("%d", &n);
if (n > con->num)
{
printf("该序号联系人不存在\n");
}
else
{
printf("%15s\t%5s\t%8s\t%15s\t%30s\n\n", "name", "age", "sex", "tel", "ads");
printf("%15s\t%5d\t%8s\t%15s\t%30s\n",
con->data[n - 1].name,
con->data[n - 1].age,
con->data[n - 1].sex,
con->data[n - 1].tel,
con->data[n - 1].ads);
}
}
//打印联系人
void dayin(struct contact *con)
{
int n = 0;
printf("%15s\t%5s\t%8s\t%15s\t%30s\n\n", "name", "age", "sex", "tel", "ads");
for( n=0;n< con->num;n++)
{
printf("%15s\t%5d\t%8s\t%15s\t%30s\n",
con->data[n].name,
con->data[n].age,
con->data[n].sex,
con->data[n].tel,
con->data[n].ads);
}
}
//修改联系人信息
void xiugai(struct contact* con)
{
int n = 0;
printf("请输入需要修改联系人的序号");
scanf("%d", &n);
if (n > con->num)
{
printf("该序号联系人不存在\n");
}
else
{
printf("\n请输入联系人姓名》");
scanf("%s", con->data[n-1].name);
printf("\n请输入联系人性别》");
scanf("%s", con->data[n-1].sex);
printf("\n请输入联系人年龄》");
scanf("%d", &con->data[n-1].age);//age是变量 需要取地址&
printf("\n请输入联系人电话》");
scanf("%s", con->data[n-1].tel);
printf("\n请输入联系人住址》");
scanf("%s", con->data[n-1].ads);
printf("\n修改成功\n");
}
}
//7、按照名字排序
void paixu(struct contact* con)
{
int i, j;
struct pepinfo tmp;
for (i = 0; i < con->num - 1; i++)
{
for (j = 0; j < con->num - 1 - i; j++)
{
if (0 < strcmp(con->data[j].name, con->data[j + 1].name))
{
tmp = con->data[j];
con->data[j] = con->data[j + 1];
con->data[j + 1] = tmp;
}
}
}
printf("完成排序\n");
}
//清空联系人
void qingkong(struct contact* con)
{
InitContact(con);
printf("清空成功\n");
}
//初始化通讯录
void InitContact(struct contact* con)
{
assert(con);
con->num = 0;
/******新增代码******/
con->data = (struct pepinfo*)calloc(DEFAULT_SZ, sizeof(struct pepinfo)); //分配默认大小并清空
if (con->data == NULL) //检查分配是否成功
{
printf("%s\n", strerror());
return;
}
con->capacity = DEFAULT_SZ;
/******************/
}
void CheckCapacity(contact* con)
{
if (con->num == con->capacity)
{
//每次扩容两个
struct pepinfo* ptr = realloc(con->data, (con->capacity +2) * sizeof( struct pepinfo));
if (ptr != NULL)
{
con->data = ptr;
con->capacity += 2;
printf("增容成功\n");
}
}
}
//
void DestroyContact(contact* con)//销毁通讯录
{
free(con->data);
con->data = NULL;
con->capacity = 0;
con->num = 0;
}