本篇主要实现一个简单的通讯录,其功能主要包括对联系人的增删改查等。
整体框架
从上图可以看出此通讯录主要包括七个功能模块:
- 增加联系人:该模块主要功能是往通讯录中增加一个新的联系人,主要包括联系人的姓名、性别、年龄、电话、住址等信息;
- 修改联系人:该模块主要功能是根据联系人姓名修改通讯录该联系人的其他信息;
- 删除联系人:该模块主要功能是根据联系人姓名删除通讯录该联系人;
- 查看联系人:该模块主要功能是根据联系人姓名查看通讯录该联系人的所有信息;
- 展示通讯录:该模块主要功能是展示通讯录中所有联系人的所有信息;
- 排序:该模块主要功能是通过通讯录中所有联系人的姓名来对通讯录进行排序;
- 清空:该功能模块主要是清空通讯录的所有内容。
功能模块的实现
由于一个联系人包含多种信息,我们没法用一个基本类型来表示,所以我们自定义一个用户类型结构体,该结构体主要包括联系人姓名、性别、年龄、电话、地址,如下:
// 用户结构体
typedef struct User {
char name[128];
char sex[16];
int age;
char phone[32];
char address[512];
} User;
我们再自定义一个通讯录结构体,主要包含两个成员,分别是联系人数组和有效联系人个数,如下:
#define MAX 1000
typedef struct UserBook {
User users[MAX];
// 有效联系人个数
int size;
} UserBook;
在主函数中我们创建一个通讯录类型的变量来保证各个模块操作的都是同一个通讯录,然后我们将该通讯录的地址传给各个模块来实现各个模块的功能。
增加联系人模块
根据入参列表传入的通讯录地址对通讯录进行操作,从键盘中输入要添加的用户信息(姓名、性别、年龄、电话、地址),将以上信息添加至通讯录中联系人数组users的size下标处(因为size之前的下标为有效联系人下标),然后对有效联系人数量size自增,添加成功后向用户反馈提示信息,包括操作结果和当前联系人数量。
void add(UserBook* ub) {
printf("请输入联系人的姓名、性别、年龄、电话、地址:");
scanf(
"%s %s %d %s %s",
ub->users[ub->size].name, ub->users[ub->size].sex,
&ub->users[ub->size].age, ub->users[ub->size].phone,
ub->users[ub->size].address
);
ub->size++;
printf("用户添加成功,当前用户数为:%d个\n", ub->size);
}
修改联系人模块
根据入参传入的通讯录地址进行修改联系人的操作,首先根据用户输入的姓名查找此用户,用一个index变量来保存查找的结果(即该联系人在通讯录中的下标),若在通讯录中没找到该联系人,则返回,并提示用户没找到;若找到该联系人,此时从键盘上输入要修改的联系人信息(姓名、性别、年龄、电话、地址),修改成功后提示用户修改成功。
void modify(UserBook* ub) {
char name[1024];
printf("请输入您要修改的姓名:");
scanf("%s", name);
int index = -1;
for (int i = 0; i < ub->size; i++) {
if (strcmp(name, ub->users[i].name) == 0) {
index = i;
break;
}
}
if (index == -1) {
printf("没找到\n");
return;
}
printf("请输入姓名、性别、年龄、电话和地址:");
scanf(
"%s %s %d %s %s",
ub->users[index].name, ub->users[index].sex,
&ub->users[index].age, ub->users[index].tele,
ub->users[index].address
);
printf("修改成功\n");
}
删除联系人模块
根据入参传入的通讯录地址进行删除联系人的操作,首先根据用户输入的姓名查找此用户,用一个index变量来保存查找的结果(即该联系人在通讯录中的下标),若在通讯录中没找到该联系人,则返回,并提示用户没找到;若找到该联系人,则将该联系人以后的所有有效联系人向前移动一个位置,并且有效联系人个数自减。
void del(UserBook* ub) {
char name[1024];
printf("请输入您要删除的姓名:");
scanf("%s", name);
int index = -1;
for (int i = 0; i < ub->size; i++) {
if (strcmp(name, ub->users[i].name) == 0) {
index = i;
break;
}
}
// 找到并删除
if (index != -1) {
for (int i = index; i < ub->size - 1; i++) {
ub->users[i] = ub->users[i + 1];
}
// 有效用户数量自减
ub->size--;
printf("删除成功\n");
return;
}
printf("没找到\n");
}
查看联系人模块
根据入参传入的通讯录地址进行查看联系人的操作,首先根据用户输入的姓名在通讯录中查找,用一个count变量来保存查找到的用户数量,然后将查找到的所有用户信息打印出来,然后向用户反馈查找到的联系人数量。
void search(UserBook* ub) {
int count = 0;
char name[1024];
printf("请输入您要查找的姓名:");
scanf("%s", name);
for (int i = 0; i < ub->size; i++) {
if (strcmp(name, ub->users[i].name) == 0) {
printf(
"[%d]. 姓名:%s 性别:%s 年龄:%d 电话:%s 地址:%s\n",
i + 1,
ub->users[i].name, ub->users[i].sex,
ub->users[i].age, ub->users[i].tele,
ub->users[i].address
);
count++;
}
}
printf("共计找到%d个\n", count);
}
展示通讯录模块
根据传入的通讯录地址来进行展示通讯录的操作,首先用一个for循环来遍历整个通讯录的有效用户,并打印所有有效用户的信息(姓名、性别、年龄、电话、地址),然后向用户反馈通讯录中所有的有效联系人数量。
void show(UserBook* ub) {
for (int i = 0; i < ub->size; i++) {
printf(
"[%d]. 姓名:%s\t性别:%s\t年龄:%d\t电话:%s\t地址:%s\n",
i + 1,
ub->users[i].name, ub->users[i].sex,
ub->users[i].age, ub->users[i].tele,
ub->users[i].address
);
}
printf("共计%d个\n", ub->size);
}
排序模块
根据传入通讯录的地址来进行排序操作,用冒泡排序根据用户姓名来进行排序,完成排序后向用户反馈提示信息。
void sort(UserBook* ub) {
for (int i = 0; i < ub->size - 1; i++) {
for (int j = 0; j < ub->size - 1 - i; j++) {
if (strcmp(ub->users[j].name, ub->users[j + 1].name) > 0) {
User tmp = ub->users[j];
ub->users[j] = ub->users[j + 1];
ub->users[j + 1] = tmp;
}
}
}
printf("排序完成\n");
}
清空模块
将传入通讯录的有效用户个数置为0,则清空成功,并向用户反馈结果。
void clear(UserBook* ub) {
ub->size = 0;
printf("清除成功\n");
}