通讯录
通讯录的功能介绍
通讯录可以用来存储1000个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址
提供方法:
1.添加联系人信息
2.删除指定联系人信息
3.查找指定联系人信息
4.修改指定联系人信息
5.显示所有联系人信息
6.清空所有联系人
7.以名字排序所有联系人
8.退出通讯录
通讯录的文件分类
这里我们需要三个文件,分别为头文件(声明函数和定义全局变量)后缀为.h,测试通讯功能后缀为.c,以及通讯录功能的实现 后缀为.c,分文件写代码是为了方便我们管理代码,清楚的知道哪个文件是用来干什么
通讯录头文件
通讯录个人信息
我们需要用结构体来描述联系人名字,电话等
#define MAX 1000
#define MAX_name 20
#define MAX_sex 5
#define MAX_tele 12
#define MAX_addr 30
struct PeInfo//表示联系人信息
{
char name[MAX_name];//数组长度最好用#define定义,因为方便我们改动
char sex[MAX_sex];
int age;
char tele[MAX_tele];
char addr[MAX_addr];
};
struct Contact
{
struct PeInfo date[MAX];//用结构体数组来存储多少个联系人
int sz;//联系人数量,也可以用作数组下标来访问第几个联系人信息
};
//初始化通讯录
void InitContact(struct Contact* pc);
//添加功能
void Add(struct Contact* pc);
//删除个人信息
void del(struct Contact* pc);
//展示个人信息
void show(struct Contact* pc);
//查找个人信息
void search(struct Contact* pc);
//修改个人信息
void update(struct Contact* pc);
//清空所有联系人
void clean(struct Contact* pc);
//排序个人信息
void my_qsort(struct Contact* pc);
测试通讯录功能文件
通讯录菜单选择
定义菜单方便用户选择功能,同时也方便我们测试代码
void menu()
{
printf("************************************\n");
printf("********1.Add 2.del ********\n");
printf("********3.search 4.update ********\n");
printf("********5.show 6.clean ********\n");
printf("********7.sort 0.exit ********\n");
printf("************************************\n");
}
通讯录的主函数
int main()
{
//创建一个结构体变量
struct Contact con;
//初始化通讯录
InitContact(&con);
int input = 0;
do
{
menu();
printf("请选择要使用的功能->");
scanf("%d", &input);
switch (input)
{
case 1:
Add(&con);
break;
case 2:
del(&con);
break;
case 3:
search(&con);
break;
case 4:
update(&con);
break;
case 5:
show(&con);
break;
case 6:
clean(&con);
break;
case 7:
my_qsort(&con);
break;
case 0:
printf("退出成功\n");
break;
default:
printf("选择无效,请重新输入\n");
break;
}
} while (input);//如果输入0则循环退出,退出功能实现
return 0;
}
通讯功能实现文件
初始化通讯录
void InitContact(struct Contact* pc)
{
assert(pc);//防止pc为空指针
pc->sz = 0;
memset(pc->date,0, MAX * sizeof(struct PeInfo));//内存设置函数参数分别为(目标空间的起始地址,设置内容,、
多少个字节) 头文件为
}
通讯录的添加功能实现
添加功能:利用结构体访问结构体数组,达到访问联系人信息的效果,然后逐一进行添加,添加完后联系人数量
加1
//添加功能
void Add(struct Contact* pc)
{
assert(pc);
if (pc->sz == MAX)
{
printf("通讯录已满");
return;
}
printf("请输入名字->");
scanf("%s", pc->date[pc->sz].name);//pc->date 通过pc来访问data数组,pc->sz 通过pc访问第几个联系人
//.name 访问data数组的成员变量name 最后进行赋值
printf("请输入性别->");
scanf("%s", pc->date[pc->sz].sex);
printf("请输入年龄->");
scanf("%d", &(pc->date[pc->sz].age));
printf("请输入电话->");
scanf("%s", pc->date[pc->sz].tele);
printf("请输入地址->");
scanf("%s", pc->date[pc->sz].addr);
pc->sz++;
printf("成功增加联系人\n");
}
通讯录删除功能实现
想要实现删除功能的前提是我们需要知道要删除谁,也就是要删除指定联系人,所以在删除之前我们需要先实现查找指定联系人,查找指定联系人我们需要一些信息,例如名字,知道名字后我们通过循环结构体数组来和名字一一比较,最后找出我们想要删除指定联系人
int find_PeInfo(struct Contact* pc, char name[])//这里是查找指定联系人函数
{
int i = 0;
for (i = 0; i < pc->sz; i++)//循环联系人数量
{
if (strcmp(pc->date[i].name, name) == 0)//用strcmp函数来比较两个字符串,如果相同strcmp函数返回0
{
return i;//获得我们需要的删除联系人的下标
}
}
return -1;
}
//删除个人信息
void del(struct Contact* pc)
{
char name[MAX_name] = "";
printf("请输入要删除人的名字:>");
scanf("%s",name);
//首先需要查到指定人
int ret = find_PeInfo(pc, name);
if (ret == -1)
{
printf("要删除的人找不到\n");
}
else
{
int i = 0;
for (i = ret; i < pc->sz-1; i++)
{
pc->date[i] = pc->date[i + 1];
}
//删除完需要减减
pc->sz--;
printf("删除成功\n");
}
}
查找指定联系人功能实现
因为我们在删除联系人的时候已经实现了通过名字找到指定联系人,所以我们再调用一次函数获得下标再打印出来
void search(struct Contact* pc)
{
char name[MAX_name];
printf("请输入要查找人的名字:>");
scanf("%s", name);
int i=find_PeInfo(pc, name);
printf("%-20s\t%-5s\t%-10s\t%-12s\t%-30s\t\n", "姓名", "性别", "年龄", "电话", "地址");
//为了控制格式对齐 %-20s 表示一个左对齐、宽度为20个字符字符串格式,不足20个字符,右侧补充相应数量的空格符
printf("%-20s\t%-5s\t%-10d\t%-12s\t%-30s\t\n", pc->date[i].name,
pc->date[i].sex,
pc->date[i].age,
pc->date[i].tele,
pc->date[i].addr);
}
修改指定联系人信息
因为已经实现了通过名字找到指定联系人,所以我们可以通过下标访问到第几个联系人。删除指定联系人我们可以把要删除的联系人后面的联系人赋值给前面,达到数据被覆盖的效果,也是删除的效果 比如有一个整形数组内容是 1 2 3 4 5 要删除3
1 2 4 5 把4赋值3的位置,把5赋值给4的位置
删除完后联系人数量减一
void del(struct Contact* pc)
{
char name[MAX_name] = "";
printf("请输入要删除人的名字:>");
scanf("%s",name);
//首先需要查到指定人
int ret = find_PeInfo(pc, name);
if (ret == -1)
{
printf("要删除的人找不到\n");
}
else
{
int i = 0;
for (i = ret; i < pc->sz-1; i++)
{
pc->date[i] = pc->date[i + 1];
}
//删除完需要减减
pc->sz--;
printf("删除成功\n");
}
}
显示所有联系人信息功能实现
这里我们可以通过循环来显示所有联系人信息
void show(const struct Contact* pc)
{
printf("%-20s\t%-5s\t%-10s\t%-12s\t%-30s\t\n", "姓名", "性别", "年龄", "电话", "地址");
int i = 0;
for (i = 0; i < pc->sz; i++)
{
printf("%-20s\t%-5s\t%-10d\t%-12s\t%-30s\t\n", pc->date[i].name,
pc->date[i].sex,
pc->date[i].age,
pc->date[i].tele,
pc->date[i].addr);
}
}
清空所有联系人
我们可以利用之前已经实现的初始化结构体成员的函数,把所有联系人信息以及联系人数量初始化为0达到清空效果
void clean(struct Contact* pc)
{
int flag = 0;
printf("是否清空所有联系人:> 1.删除 0.取消\n");//为了防止用户误清空联系人
do{
scanf("%d", &flag);
if (flag == 1)
{
pc->sz = 0;
memset(pc->date, 0, MAX * sizeof(struct PeInfo));
printf("清除成功");
return;
}
else if (flag == 0)
{
printf("取消成功\n");
return;
}
else
{
printf("输入无效,请重新输入\n");
}
} while (flag);
}
以名字排序所有联系人功能实现
排序我们可以使用库函数qsort ,它的参数为void qsort (void* base 待排序数据的起始地址
, size_t num, 待排序数据的元素个数
size_t size, 待排序数据元素的大小(单位是字节)
int (compar)(const void p1,const void* p2)); 比较两个元素大小的函数指针
int CmpByAge(const void* e1, const void* e2)//按照名字排序
{
return (((struct PeInfo*)e1)->age - ((struct PeInfo*)e2)->age);
}
int CmpByName(const void* e1, const void* e2)//按照年龄排序
{
return strcmp(((struct PeInfo*)e1)->name, ((struct PeInfo*)e2)->name);
}
//排序个人信息
void my_qsort(struct Contact* pc)
{
int flag = 0;
printf("请选择 1.年龄排序或 2.名字排序:>");
scanf("%d", &flag);
if (flag == 1)
{
qsort(pc->date, pc->sz, sizeof(struct PeInfo), CmpByAge);//按照年龄排序
}
else
{
qsort(pc->date, pc->sz, sizeof(struct PeInfo), CmpByName);//按照名字排序
}
}
退出通讯录功能实现
这里我们放到主函数里面,用变量input来做循环条件,如果用户输入0,则循环退出,退出功能实现
完整代码展示
//通讯录头文件
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#define MAX 1000
#define MAX_name 20
#define MAX_sex 5
#define MAX_tele 12
#define MAX_addr 30
//个人信息
struct PeInfo
{
char name[MAX_name];
char sex[MAX_sex];
int age;
char tele[MAX_tele];
char addr[MAX_addr];
};
//表示通讯录几个人 一个的信息
struct Contact
{
struct PeInfo date[MAX];
int sz;
};
//初始化通讯录
void InitContact(struct Contact* pc);
//添加功能
void Add(struct Contact* pc);
//删除个人信息
void del(struct Contact* pc);
//展示个人信息
void show(struct Contact* pc);
//查找个人信息
void search(struct Contact* pc);
//修改个人信息
void update(struct Contact* pc);
//清空所有联系人
void clean(struct Contact* pc);
//排序个人信息
void my_qsort(struct Contact* pc);
//测试通讯录文件
#include "通讯录头文件.h"
void menu()
{
printf("************************************\n");
printf("********1.Add 2.del ********\n");
printf("********3.search 4.update ********\n");
printf("********5.show 6.clean ********\n");
printf("********7.sort 0.exit ********\n");
printf("************************************\n");
}
int main()
{
//创建一个结构体变量
struct Contact con;
//初始化通讯录
InitContact(&con);
int input = 0;
do
{
menu();
printf("请选择要使用的功能->");
scanf("%d", &input);
switch (input)
{
case 1:
Add(&con);
break;
case 2:
del(&con);
break;
case 3:
search(&con);
break;
case 4:
update(&con);
break;
case 5:
show(&con);
break;
case 6:
clean(&con);
break;
case 7:
my_qsort(&con);
break;
case 0:
printf("退出成功\n");
break;
default:
printf("选择无效,请重新输入\n");
break;
}
} while (input);
return 0;
}
//通讯录功能实现文件
#include "通讯录头文件.h"
//初始化通讯录
void InitContact(struct Contact* pc)
{
assert(pc);
pc->sz = 0;
memset(pc->date,0, MAX * sizeof(struct PeInfo));
}
//添加功能
void Add(struct Contact* pc)
{
assert(pc);
if (pc->sz == MAX)
{
printf("通讯录已满");
return;
}
printf("请输入名字->");
scanf("%s", pc->date[pc->sz].name);
printf("请输入性别->");
scanf("%s", pc->date[pc->sz].sex);
printf("请输入年龄->");
scanf("%d", &(pc->date[pc->sz].age));
printf("请输入电话->");
scanf("%s", pc->date[pc->sz].tele);
printf("请输入地址->");
scanf("%s", pc->date[pc->sz].addr);
pc->sz++;
printf("成功增加联系人\n");
}
int find_PeInfo(struct Contact* pc, char name[])
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (strcmp(pc->date[i].name, name) == 0)
{
return i;
}
}
return -1;
}
//删除个人信息
void del(struct Contact* pc)
{
char name[MAX_name] = "";
printf("请输入要删除人的名字:>");
scanf("%s",name);
//首先需要查到指定人
int ret = find_PeInfo(pc, name);
if (ret == -1)
{
printf("要删除的人找不到\n");
}
else
{
int i = 0;
for (i = ret; i < pc->sz-1; i++)
{
pc->date[i] = pc->date[i + 1];
}
//删除完需要减减
pc->sz--;
printf("删除成功\n");
}
}
//展示个人信息
void show(const struct Contact* pc)
{
printf("%-20s\t%-5s\t%-10s\t%-12s\t%-30s\t\n", "姓名", "性别", "年龄", "电话", "地址");
int i = 0;
for (i = 0; i < pc->sz; i++)
{
printf("%-20s\t%-5s\t%-10d\t%-12s\t%-30s\t\n", pc->date[i].name,
pc->date[i].sex,
pc->date[i].age,
pc->date[i].tele,
pc->date[i].addr);
}
}
//查找个人信息
void search(struct Contact* pc)
{
char name[MAX_name];
printf("请输入要查找人的名字:>");
scanf("%s", name);
int i=find_PeInfo(pc, name);
printf("%-20s\t%-5s\t%-10s\t%-12s\t%-30s\t\n", "姓名", "性别", "年龄", "电话", "地址");
printf("%-20s\t%-5s\t%-10d\t%-12s\t%-30s\t\n", pc->date[i].name,
pc->date[i].sex,
pc->date[i].age,
pc->date[i].tele,
pc->date[i].addr);
}
//修改个人信息
void update(struct Contact* pc)
{
char name[MAX_name] = "";
printf("请输入指定修改人的名字:>");
scanf("%s", name);
int ret=find_PeInfo(pc, name);
if (ret == -1)
{
printf("要修改的人不存在");
}
else
{
printf("请输入要修改性别->");
scanf("%s", pc->date[ret].sex);
printf("请输入要修改年龄->");
scanf("%d", &(pc->date[ret].age));
printf("请输入要修改电话->");
scanf("%s", pc->date[ret].tele);
printf("请输入要修地址->");
scanf("%s", pc->date[ret].addr);
}
}
//清空所有联系人
void clean(struct Contact* pc)
{
int flag = 0;
printf("是否清空所有联系人:> 1.删除 0.取消\n");
do{
scanf("%d", &flag);
if (flag == 1)
{
pc->sz = 0;
memset(pc->date, 0, MAX * sizeof(struct PeInfo));
printf("清除成功");
return;
}
else if (flag == 0)
{
printf("取消成功\n");
return;
}
else
{
printf("输入无效,请重新输入\n");
}
} while (flag);
}
int CmpByAge(const void* e1, const void* e2)
{
return (((struct PeInfo*)e1)->age - ((struct PeInfo*)e2)->age);
}
int CmpByName(const void* e1, const void* e2)
{
return strcmp(((struct PeInfo*)e1)->name, ((struct PeInfo*)e2)->name);
}
//排序个人信息
void my_qsort(struct Contact* pc)
{
int flag = 0;
printf("请选择 1.年龄排序或 2.名字排序:>");
scanf("%d", &flag);
if (flag == 1)
{
qsort(pc->date, pc->sz, sizeof(struct PeInfo), CmpByAge);
}
else
{
qsort(pc->date, pc->sz, sizeof(struct PeInfo), CmpByName);
}
}
最后点赞收藏哦 ,如有问题也可以在下方评论