学习了结构体之后,我们就可以尝试实现一个静态版本的通讯录了。
这个通讯录,可以存储1000个人的信息,每个人的信息包括:姓名,年龄,电话,性别,住址;功能包括:1.新增联系人,2.删除联系人,3.查找联系人,4.修改联系人,5.查看所有联系人,6.删除所有联系人,7.对所有联系人进行排序(此版本是最基础的通讯录,后续会出更加全面的升级版本)
一、通讯录菜单
菜单可以实现和用户的交互。那么作为一个通讯录怎么能没有菜单呢?我们第一步先来设计一个菜单选项:
二、通讯录主函数
写完了通讯录菜单后,我们就要对主函数进行设计,代码如下:
#include "contact.h"
//为提高对代码阅读者的可读性,这里使用枚举来代替case的0,1,2,3,4,5,6
enum func
{
Exit,
add,
del,
search,
modify,
show,
del_all,
sort
};
int main()
{
int input = 0;
struct contact_all con_all;
Init(&con_all);//初始化通讯录
do
{
menu();
printf("请输入:");
scanf("%d", &input);
switch (input)
{
case add:
Add(&con_all);
break;
case del:
Del(&con_all);
break;
case search:
Search(&con_all);
break;
case modify:
Modify(&con_all);
break;
case show:
Show(&con_all);
break;
case del_all:
Del_all(&con_all);
break;
case sort:
Sort(&con_all);
break;
case Exit:
printf("已经退出通讯录了\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
三、枚举主函数内部选项
为了增加代码的可读性,我们可以用枚举把1变成add,2变成del ......,这样就不用再回到最上面菜单的地方看每个数字代表什么意思了。
四、定义联系人及通讯录
这一步是为了实现前言中的通讯录内容以及联系人内容,为此我们需要用到结构体
(一)定义联系人内容(结构体)
代码如下:
struct contact_one
{
char name[20];
int age;
char sex[10];
char tele[20];
char addr[20];
}con_one;
(二)定义通讯录内容(结构体)
代码如下:
struct contact_all
{
struct contact_one con_one [max_num];
int sz;
}con_all;
五、全局变量声明
我们可以#define 一些常量,这样在以后需要修改的时候可以很方便,例如通讯录中联系人的数量.......
六、初始化通讯录
代码如下:
void Init(struct contact_all* pc)
{
assert(pc);
pc->sz = 0;
memset(pc->con_one, 0, sizeof(pc->con_one));
}
七、通过姓名查找函数
代码如下:
void Search(struct contact_all* pc)
{
assert(pc);
if (pc->sz == 0)
{
printf("当前通讯录暂无联系人\n");
return;
}
else//根据姓名查找
{
char search_name[20] = { 0 };
printf("请输入要查找的联系人的姓名:");
scanf("%s", search_name);
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (strcmp(search_name, pc->con_one[i].name) == 0)
{
printf("找到了:\n");
printf("%-8s %-4d %-5s %-15s %-10s\n",
pc->con_one[i].name, pc->con_one[i].age, pc->con_one[i].sex, pc->con_one[i].tele, pc->con_one[i].addr);
return;
}
}
printf("没有此联系人\n");
}
}
八、实现通讯录功能
(一)新增联系人
void Add(struct contact_all* pc)
{
assert(pc);
if (pc->sz == max_num)
{
printf("联系人已满\n");//你怎么那么多联系人?
return;
}
else
{
printf("请添加新的联系人的姓名:\n");
scanf("%s,", pc->con_one[pc->sz].name);
printf("请添加新的联系人的年龄:\n");
scanf("%d,", &pc->con_one[pc->sz].age);
printf("请添加新的联系人的性别:\n");
scanf("%s,", pc->con_one[pc->sz].sex);
printf("请添加新的联系人的号码:\n");
scanf("%s,", pc->con_one[pc->sz].tele);
printf("请添加新的联系人的地址:\n");
scanf("%s,", pc->con_one[pc->sz].addr);
pc->sz++;
printf("添加成功\n");
}
}
模拟效果:
(二)删除联系人
void Del(struct contact_all* pc)
{
assert(pc);
if (pc->sz == 0)
{
printf("当前还没有联系人,暂不能进行删除操作\n");
return;
}
else//根据姓名删除
{
char del_name[20] = { 0 };
printf("请输入要删除的联系人的名字:");
scanf("%s", del_name);
int i = 0;
for (i = 0; i<pc->sz; i++)
{
if (strcmp(del_name, pc->con_one[i].name) == 0)
{
for (i; i < pc->sz - 1; i++)//覆盖
{
pc->con_one[i] = pc->con_one[i + 1];
}
pc->sz--;
printf("删除成功\n");
return;
}
}
printf("没有此联系人\n");
}
}
模拟效果:
(三)查找联系人
void Search(struct contact_all* pc)
{
assert(pc);
if (pc->sz == 0)
{
printf("当前通讯录暂无联系人\n");
return;
}
else//根据姓名查找
{
char search_name[20] = { 0 };
printf("请输入要查找的联系人的姓名:");
scanf("%s", search_name);
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (strcmp(search_name, pc->con_one[i].name) == 0)
{
printf("找到了:\n");
printf("%-8s %-4d %-5s %-15s %-10s\n",
pc->con_one[i].name, pc->con_one[i].age, pc->con_one[i].sex, pc->con_one[i].tele, pc->con_one[i].addr);
return;
}
}
printf("没有此联系人\n");
}
}
演示效果:
(四)修改联系人
void Modify(struct contact_all* pc)
{
assert(pc);
if (pc->sz == 0)
{
printf("通讯录没人,无法修改\n");
return;
}
else//根据姓名查找(假设)
{
char search_name[20] = { 0 };
printf("请输入要修改的联系人的姓名:");
scanf("%s", search_name);
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (strcmp(search_name, pc->con_one[i].name) == 0)
{
printf("找到了:\n");
printf("%-8s %-4d %-5s %-15s %-10s\n",
pc->con_one[i].name, pc->con_one[i].age, pc->con_one[i].sex, pc->con_one[i].tele, pc->con_one[i].addr);
printf("请修改联系人的姓名:\n");
scanf("%s,", pc->con_one[i].name);
printf("请修改联系人的年龄:\n");
scanf("%d,", &pc->con_one[i].age);
printf("请修改联系人的性别:\n");
scanf("%s,", pc->con_one[i].sex);
printf("请修改联系人的号码:\n");
scanf("%s,", pc->con_one[i].tele);
printf("请修改联系人的地址:\n");
scanf("%s,", pc->con_one[i].addr);
printf("修改成功\n");
return;
}
}
printf("没有此联系人\n");
}
}
演示效果:
(五)显示所有联系人
void Show(struct contact_all* pc)
{
assert(pc);
printf("%-8s %-4s %-5s %-15s %-10s\n", "名字", "年龄", "性别", "电话", "地址");
int i = 0;
for (i = 0; i < pc->sz; i++)
{
printf("%-8s %-4d %-5s %-15s %-10s\n",
pc->con_one[i].name,pc->con_one[i].age,pc->con_one[i].sex,pc->con_one[i].tele,pc->con_one[i].addr);
}
}
演示效果:
(六)按姓名排序所有联系人
int cmp_by_name(const void* e1,const void* e2)
{
return strcmp(((struct contact_one*)e1)->name,((struct contact_one*)e2)->name);
}
void Sort(struct contact_all* pc)//对名字排序
{
assert(pc);
qsort(pc->con_one, pc->sz, sizeof(con_one), cmp_by_name);//快排
printf("排序完成\n");
}
九、头文件
写到这里我们是不是忘记了点什么?没错,那就是头文件,不引用头文件编译器就会报错,所以我们在写代码的时候一定要加上头文件。
代码如下:
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
十、完整代码
test.c :
#include "contact.h"
void menu()
{
printf("**********************************\n");
printf("***** 1.add 2.del ****\n");
printf("***** 3.search 4.modify ****\n");
printf("***** 5.show 6.del_all ****\n");
printf("***** 7.sort 0.exit ****\n");
printf("**********************************\n");
}
//为提高对代码阅读者的可读性,这里使用枚举来代替case的0,1,2,3,4,5,6
enum func
{
Exit,
add,
del,
search,
modify,
show,
del_all,
sort
};
int main()
{
int input = 0;
struct contact_all con_all;
Init(&con_all);//初始化通讯录
do
{
menu();
printf("请输入:");
scanf("%d", &input);
switch (input)
{
case add:
Add(&con_all);
break;
case del:
Del(&con_all);
break;
case search:
Search(&con_all);
break;
case modify:
Modify(&con_all);
break;
case show:
Show(&con_all);
break;
case del_all:
Del_all(&con_all);
break;
case sort:
Sort(&con_all);
break;
case Exit:
printf("已经退出通讯录了\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
contact.h :
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#define max_num 1000
struct contact_one
{
char name[20];
int age;
char sex[10];
char tele[20];
char addr[20];
}con_one;
struct contact_all
{
struct contact_one con_one [max_num];
int sz;
}con_all;
void Init(struct contact_all* pc);//初始化通讯录
void Add(struct contact_all* pc);//增加
void Del(struct contact_all* pc);//删除
void Search(struct contact_all* pc);//查找
void Modify(struct contact_all* pc);//修改
void Del_all(struct contact_all* pc);//清空所有数据
void Sort(struct contact_all* pc);//排序
void Show(struct contact_all* pc);//显示
contact.c :
#include "contact.h"
void Init(struct contact_all* pc)
{
assert(pc);
pc->sz = 0;
memset(pc->con_one, 0, sizeof(pc->con_one));
}
void Add(struct contact_all* pc)
{
assert(pc);
if (pc->sz == max_num)
{
printf("联系人已满\n");//你怎么那么多联系人?
return;
}
else
{
printf("请添加新的联系人的姓名:\n");
scanf("%s,", pc->con_one[pc->sz].name);
printf("请添加新的联系人的年龄:\n");
scanf("%d,", &pc->con_one[pc->sz].age);
printf("请添加新的联系人的性别:\n");
scanf("%s,", pc->con_one[pc->sz].sex);
printf("请添加新的联系人的号码:\n");
scanf("%s,", pc->con_one[pc->sz].tele);
printf("请添加新的联系人的地址:\n");
scanf("%s,", pc->con_one[pc->sz].addr);
pc->sz++;
printf("添加成功\n");
}
}
void Del(struct contact_all* pc)
{
assert(pc);
if (pc->sz == 0)
{
printf("当前还没有联系人,暂不能进行删除操作\n");
return;
}
else//根据姓名删除
{
char del_name[20] = { 0 };
printf("请输入要删除的联系人的名字:");
scanf("%s", del_name);
int i = 0;
for (i = 0; i<pc->sz; i++)
{
if (strcmp(del_name, pc->con_one[i].name) == 0)
{
for (i; i < pc->sz - 1; i++)//覆盖
{
pc->con_one[i] = pc->con_one[i + 1];
}
pc->sz--;
printf("删除成功\n");
return;
}
}
printf("没有此联系人\n");
}
}
void Search(struct contact_all* pc)
{
assert(pc);
if (pc->sz == 0)
{
printf("当前通讯录暂无联系人\n");
return;
}
else//根据姓名查找
{
char search_name[20] = { 0 };
printf("请输入要查找的联系人的姓名:");
scanf("%s", search_name);
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (strcmp(search_name, pc->con_one[i].name) == 0)
{
printf("找到了:\n");
printf("%-8s %-4d %-5s %-15s %-10s\n",
pc->con_one[i].name, pc->con_one[i].age, pc->con_one[i].sex, pc->con_one[i].tele, pc->con_one[i].addr);
return;
}
}
printf("没有此联系人\n");
}
}
void Modify(struct contact_all* pc)
{
assert(pc);
if (pc->sz == 0)
{
printf("通讯录没人,无法修改\n");
return;
}
else//根据姓名查找(假设)
{
char search_name[20] = { 0 };
printf("请输入要修改的联系人的姓名:");
scanf("%s", search_name);
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (strcmp(search_name, pc->con_one[i].name) == 0)
{
printf("找到了:\n");
printf("%-8s %-4d %-5s %-15s %-10s\n",
pc->con_one[i].name, pc->con_one[i].age, pc->con_one[i].sex, pc->con_one[i].tele, pc->con_one[i].addr);
printf("请修改联系人的姓名:\n");
scanf("%s,", pc->con_one[i].name);
printf("请修改联系人的年龄:\n");
scanf("%d,", &pc->con_one[i].age);
printf("请修改联系人的性别:\n");
scanf("%s,", pc->con_one[i].sex);
printf("请修改联系人的号码:\n");
scanf("%s,", pc->con_one[i].tele);
printf("请修改联系人的地址:\n");
scanf("%s,", pc->con_one[i].addr);
printf("修改成功\n");
return;
}
}
printf("没有此联系人\n");
}
}
int cmp_by_name(const void* e1,const void* e2)
{
return strcmp(((struct contact_one*)e1)->name,((struct contact_one*)e2)->name);
}
void Sort(struct contact_all* pc)//对名字排序
{
assert(pc);
qsort(pc->con_one, pc->sz, sizeof(con_one), cmp_by_name);
printf("排序完成\n");
}
void Show(struct contact_all* pc)
{
assert(pc);
printf("%-8s %-4s %-5s %-15s %-10s\n", "名字", "年龄", "性别", "电话", "地址");
int i = 0;
for (i = 0; i < pc->sz; i++)
{
printf("%-8s %-4d %-5s %-15s %-10s\n",
pc->con_one[i].name,pc->con_one[i].age,pc->con_one[i].sex,pc->con_one[i].tele,pc->con_one[i].addr);
}
}
void Del_all(struct contact_all* pc)
{
assert(pc);
memset(pc->con_one, 0, sizeof(pc->con_one));
pc->sz = 0;
printf("已清空所有联系人\n");
return;
}