数据结构之实现“通讯录”

news/2024/10/21 0:29:36/

                                               大家先赞后看,养成好习惯

你们的点赞和关注还有收藏就是我的动力!!!

目录

前言

一、通讯录文件的创建和联系人结构体定义

1.1 文件创建

1.2 联系人结构体定义

二、通讯录的功能实现

2.1通讯录初始化

2.2通讯录销毁

2.3添加联系人

2.4删除联系人

2.5查找联系人(包含显现联系人)

2.6修改通讯录

2.7展示通讯录

2.8菜单的创建 (与扫雷、猜数字相似)

三、使用通讯录储存联系人

四、结合文件操作来储存信息

五、代码展示

5.1通讯录头文件

5.2通讯录源文件 

总结


前言

“通讯录”是基于顺序表的基础上实现的项目,要熟悉顺序表才比较容易看懂和完成通讯录项目。在这个博客里面不会来介绍之前的东西,之前没看懂的可以到这【数据结构之“顺序表”】-CSDN博客

一、通讯录文件的创建和联系人结构体定义

1.1 文件创建

加上之前顺序表的两个文件一共是五个文件。

test.c是实现联系人储存的文件,contact.c是通讯录的源文件,contact.h是通讯录的头文件,seqlist.c和seqlist.h是之前的顺序表的源文件和头文件。(源文件是功能实现的代码,头文件是用来包含一些头文件和定义一些东西)

1.2 联系人结构体定义

我们这里的联系人信息包含:姓名、性别、年龄 、电话、地址

typedef struct PersonInfo//通讯录
{char name[Max_name];//姓名char gender[Max_gender];//性别int age;//年龄char tel[Max_tel];//电话char addr[Max_addr];//地址
}PeoInfo;//命名为PeoInfo

二、通讯录的功能实现

2.1通讯录初始化

我们就调用一下顺序表的初始化就可以了,因为在顺序表的arr中存放每一个结构体(也就是联系人的信息)就是PersonInfo。

//通讯录初始化
void contactInit(contact * con)
{//这里的con就是sl也就是一个结构体指针初始化为NULL//我们直接调用顺序表的初始化SLInit(con);//初始化
}

2.2通讯录销毁

销毁也同初始化,直接调用顺序表的销毁。

//通讯录销毁
void contactDestroy(contact* con)
{SLDestroy(con);//销毁
}

2.3添加联系人

也就是给结构体里面的人赋初值,然后调用一下顺序表的插入函数(头插、尾插都行)。

//添加通讯录联系人
void contactAdd(contact* con)
{PeoInfo info;//同SL sl;定义一个结构体,方便使用printf("请输入联系人姓名:\n");scanf("%s", info.name);printf("请输入联系人性别:\n");scanf("%s", info.gender);printf("请输入联系人年龄:\n");scanf("%d", &info.age);printf("请输入联系人电话:\n");scanf("%s", info.tel);printf("请输入联系人地址:\n");scanf("%s", info.addr);SLPushFront(con,info);//头插联系人printf("添加联系人成功!\n");
}

2.4删除联系人

删除联系人有很多方法,可以通过姓名、性别、年龄 、电话、地址 五种方法随便选择一种。

我这里演示的是通过姓名来删除联系人,剩下的几种大家可以自行尝试!!。

想法我们要遍历每一个结构体里面的info.name然后判断与要被删除的联系人姓名,然后返回下标进行了(顺序表本质就是一个数组,可以通过下标来找到),调用查找联系人返回下标函数,我们比较的是字符使用要用strcmp函数,然后调用一下顺序表指定位置的删除就可以了。

//查找联系人,并返回下标
int contactFindName(contact* con,char name[Max_name])
{//还可以通过其他来返回下标,地址,电话都行,要看传来的参数是什么。for (int i = 0;i < con->size;i++){if (0 == strcmp(con->arr[i].name, name))//strcmp字符串比较函数{//找到了return i;}}//没找到return -1;
}//删除联系人void contactDel(contact* con)
{//删除前要检查删除的数据是否存在//就要先查找数据char name[Max_name];printf("请输入你要删除的联系人姓名:\n");scanf("%s", name);int pos = contactFindName(con, name);if (pos < 0){printf("删除的联系人不存在!\n");return;}SLErase(con,pos);//pos是删除元素的下标printf("删除成功!\n");
}

2.5查找联系人(包含显现联系人)

查找联系人和删除联系人很像,只比删除联系人少了删除数据。

//查找通讯录联系人void contactFind(contact* con){char name[Max_name];printf("请输入查找的联系人姓名:\n");scanf("%s", name);int pos = contactFindName(con, name);if (pos < 0){printf("查找的联系人不存在,查找失败!\n");return;}printf("查找成功\n");printf("姓名 性别 年龄 电话 地址\n");printf("%-5s %2s %3d %5s %5s\n", con->arr[pos].name,con->arr[pos].gender,con->arr[pos].age,con->arr[pos].tel,con->arr[pos].addr);}

2.6修改通讯录

本质上和删除差不多,还是通过返回下标来重新修改联系人

//修改通讯录联系人
void contactModify(contact* con)
{char name[Max_name];printf("请输入要修改的联系人名字:\n");scanf("%s", name);int pos = contactFindName(con,name);if (pos < 0){printf("修改的联系人不存在,修改失败!\n");return;}PeoInfo info;printf("请输入修改后联系人姓名:\n");scanf("%s", con->arr[pos].name);printf("请输入修改后联系人性别:\n");scanf("%s", con->arr[pos].gender);printf("请输入修改后联系人年龄:\n");scanf("%d", &con->arr[pos].age);printf("请输入修改后联系人电话:\n");scanf("%s", con->arr[pos].tel);printf("请输入修改后联系人地址:\n");scanf("%s", con->arr[pos].addr);printf("修改成功!\n");
}

2.7展示通讯录

通过循环来打印联系人信息,这时就要用到顺序表里面的有效个数(size)来作为循环的判断条件。

//展示通讯录联系人
void contactShow(contact* con)
{for (int i = 0;i < con->size;i++)//呈现所有的信息{printf("姓名 性别 年龄 电话 地址\n");printf("%-5s %2s %3d %5s %5s\n", con->arr[i].name,con->arr[i].gender,con->arr[i].age,con->arr[i].tel,con->arr[i].addr);}printf("呈现完毕!\n");
}

2.8菜单的创建 (与扫雷、猜数字相似)

void menu()//菜单  目录
{printf("***********通讯录**********\n");printf("**1.添加用户***2.删除用户**\n");printf("**3.查找用户***4.修改用户**\n");printf("**5.显示用户***0.退出程序**\n");
}

三、使用通讯录储存联系人

#define _CRT_SECURE_NO_WARNINGS
//用来测试代码
#include"Seqlist.h"int main()
{contact con;contactInit(&con);//初始化int input = -1;do{menu();printf("请你选择操作:\n");scanf("%d", &input);switch (input){case 1: contactAdd(&con);break;case 2:contactDel(&con);break;case 3:contactFind(&con);break;case 4:contactModify(&con);break;case 5:contactShow(&con);break;default:printf("输入操作错误,重新输入!\n");break;//default 后面break 可写可不写}} while (input);//input 等价于 input!=0contactDestroy(&con);//销毁return 0;
}

这是主函数(切忌俩个头文件互相包含)

我来演示一下

联系人 姓名:恐龙、性别:男、年龄:18、电话:666666、地址:侏罗纪公园。

拼音不好见谅!!!!

四、结合文件操作来储存信息

这里就不细讲了文件操作,可以看之前的​​​​​​喉咙疼的恐龙又来给大家介绍”芝士了“ 那就是文件操作-CSDN博客

//读取数据到contact.txt文件中
void contactLoad(contact* con)
{FILE* pf = fopen("contact.txt","rb");//二进制读if (pf = NULL){perror("fopen error:");return;}PeoInfo info;while (fread(&info, sizeof(info), 1, pf)){SLPushFront(con, info);}fclose(pf);//关闭pf = NULL;//防止出现空指针printf("历史数据读取成功!\n");
}//写数据到contact.txt文件中
void contactSave(contact* con)
{FILE* pf = fopen("contact.txt","wb");if (pf == NULL){perror("fopen error!");return;}for (int sz = 0;sz < con->size;sz++){fwrite(con->arr+sz, sizeof(PeoInfo), 1, pf);//con->arr[sz]不行,这里要地址,&con->arr[sz].}fclose(pf);//关闭pf = NULL;//防止出现空指针printf("通讯录数据保存成功!\n");
}

五、代码展示

5.1通讯录头文件

contact.h
#pragma once
#define Max_name 20
#define Max_gender 10
#define Max_tel 15
#define Max_addr 20typedef struct Seqlist contact;//前置声明,因为不可以相互包含头文件,会报错。
//总结通讯录项目的原理:基于顺序表,在顺序表的数组中存放每一个结构体(也就是联系人的信息)
typedef struct PersonInfo//通讯录
{char name[Max_name];//姓名char gender[Max_gender];//性别int age;//年龄char tel[Max_tel];//电话char addr[Max_addr];//地址
}PeoInfo;//通讯录初始化
void contactInit(contact* con);
//通讯录的销毁
void contactDestroy(contact* con);
//添加通讯录联系人
void contactAdd(contact* con);
//删除通讯录联系人
void contactDel(contact* con);
//查找通讯录联系人
void contactFind(contact* con);
//修改通讯录联系人
void contactModify(contact* con);
//展示通讯录联系人
void contactShow(contact* con);

5.2通讯录源文件 

contact.c
#define _CRT_SECURE_NO_WARNINGS
#include"Contact.h"
#include"Seqlist.h"//读取数据到contact.txt文件中
void contactLoad(contact* con)
{FILE* pf = fopen("contact.txt","rb");//二进制读if (pf = NULL){perror("fopen error:");return;}PeoInfo info;while (fread(&info, sizeof(info), 1, pf)){SLPushFront(con, info);}fclose(pf);//关闭pf = NULL;//防止出现空指针printf("历史数据读取成功!\n");
}//写数据到contact.txt文件中
void contactSave(contact* con)
{FILE* pf = fopen("contact.txt","wb");if (pf == NULL){perror("fopen error!");return;}for (int sz = 0;sz < con->size;sz++){fwrite(con->arr+sz, sizeof(PeoInfo), 1, pf);//con->arr[sz]不行,这里要地址,&con->arr[sz].}fclose(pf);//关闭pf = NULL;//防止出现空指针printf("通讯录数据保存成功!\n");
}//通讯录初始化
void contactInit(contact * con)
{//这里的con就是sl也就是一个结构体指针初始化为NULL//我们直接调用顺序表的初始化SLInit(con);//初始化
}//通讯录销毁
void contactDestroy(contact* con)
{SLDestroy(con);//销毁
}//添加通讯录联系人
void contactAdd(contact* con)
{PeoInfo info;//同SL sl;定义一个结构体,方便使用printf("请输入联系人姓名:\n");scanf("%s", info.name);printf("请输入联系人性别:\n");scanf("%s", info.gender);printf("请输入联系人年龄:\n");scanf("%d", &info.age);printf("请输入联系人电话:\n");scanf("%s", info.tel);printf("请输入联系人地址:\n");scanf("%s", info.addr);SLPushFront(con,info);//头插联系人printf("添加联系人成功!\n");
}//查找联系人,并返回下标
int contactFindName(contact* con,char name[Max_name])
{//还可以通过其他来返回下标,地址,电话都行,要看传来的参数是什么。for (int i = 0;i < con->size;i++){if (0 == strcmp(con->arr[i].name, name))//strcmp字符串比较函数{//找到了return i;}}//没找到return -1;
}//删除联系人void contactDel(contact* con)
{//删除前要检查删除的数据是否存在//就要先查找数据char name[Max_name];printf("请输入你要删除的联系人姓名:\n");scanf("%s", name);int pos = contactFindName(con, name);if (pos < 0){printf("删除的联系人不存在!\n");return;}SLErase(con,pos);//pos是删除元素的下标printf("删除成功!\n");
}//查找通讯录联系人void contactFind(contact* con)//err{char name[Max_name];printf("请输入查找的联系人姓名:\n");scanf("%s", name);int pos = contactFindName(con, name);if (pos < 0){printf("查找的联系人不存在,查找失败!\n");return;}printf("查找成功\n");printf("姓名 性别 年龄 电话 地址\n");printf("%-5s %2s %3d %5s %5s\n", con->arr[pos].name,con->arr[pos].gender,con->arr[pos].age,con->arr[pos].tel,con->arr[pos].addr);}//修改通讯录联系人void contactModify(contact* con){char name[Max_name];printf("请输入要修改的联系人名字:\n");scanf("%s", name);int pos = contactFindName(con,name);if (pos < 0){printf("修改的联系人不存在,修改失败!\n");return;}PeoInfo info;printf("请输入修改后联系人姓名:\n");scanf("%s", con->arr[pos].name);printf("请输入修改后联系人性别:\n");scanf("%s", con->arr[pos].gender);printf("请输入修改后联系人年龄:\n");scanf("%d", &con->arr[pos].age);printf("请输入修改后联系人电话:\n");scanf("%s", con->arr[pos].tel);printf("请输入修改后联系人地址:\n");scanf("%s", con->arr[pos].addr);printf("修改成功!\n");}//展示通讯录联系人void contactShow(contact* con){for (int i = 0;i < con->size;i++)//呈现所有的信息{printf("姓名 性别 年龄 电话 地址\n");printf("%-5s %2s %3d %5s %5s\n", con->arr[i].name,con->arr[i].gender,con->arr[i].age,con->arr[i].tel,con->arr[i].addr);}printf("呈现完毕!\n");}

总结

通讯录这个项目你只要完全了解了顺序表解决不困难,要理解通讯录结构体每一个联系人就是顺序表中的arr动态数组里面的一个成员。我们还可以把这些联系人的信息以文件的形式储存起来,这就要运用到我们之前学习过的文件操作。本人感觉顺序表和通讯录会比链表复杂,后面还会为大家介绍单链表和双链表,大家敬请期待吧!!


http://www.ppmy.cn/news/1465902.html

相关文章

像艺术家一样工作:前言

名人名言 “艺术是盗窃” —— 巴勃罗毕加索 “不成熟的诗人模仿&#xff0c;成熟的诗人偷窃&#xff1b;对于偷窃得到的艺术&#xff0c;坏的诗人丑化它&#xff0c;好的诗人加入自己的理解&#xff0c;使它变得更好&#xff0c;至少会让它有点不同。最优秀的诗人&#xff0…

思迈特受邀参加工信部等权威机构行业盛会,探讨AI领域前沿技术

近日&#xff0c;思迈特软件作为国产BI领域知名厂商&#xff0c;多次受邀出席行业盛会&#xff0c;与众多业内专家学者、行业精英及知名企业代表等汇聚一堂共襄盛会&#xff0c;探讨行业前沿热点研究及最新趋势&#xff0c;分享企业数字化建设创新成果与成功实践&#xff0c;共…

大泽动力车载柴油发电机的特点和优势有哪些

大泽动力车载柴油发电机具有一系列显著的特点和优势&#xff0c;以下是对其的详细介绍&#xff1a; 低噪音性能&#xff1a;大泽动力车载柴油发电机具备明显的低噪音性能&#xff0c;其噪音限值在距离机组7米处测得为70dB(A)&#xff0c;这为用户提供了一个相对安静的工作环境…

ChatGPT AI专题资料合集【65GB】

介绍 ChatGPT & AI专题资料合集【65GB】 &#x1f381;【七七云享】资源仓库&#xff0c;海量资源&#xff0c;无偿分享√

[AIGC] DAG任务调度的概述与实践

DAG(Directed Acyclic Graph&#xff0c;有向无环图)作为任务调度的基础模型&#xff0c;在大规模数据处理和计算过程中有着广泛的应用。本文将对DAG模型的原理进行解释并列出一些常用的任务调度工具。 文章目录 一、什么是DAG&#xff1f;二、DAG任务调度的原理三、常用的DAG任…

mathtype7最新产品密钥激活2024最新

MathType是一款专业的数学公式编辑器&#xff0c;广泛应用于教育、科研和出版等领域。随着在线教育和远程工作的兴起&#xff0c;MathType的使用场景更加广泛&#xff0c;成为教师、学生、研究人员和专业作家必不可少的工具之一。本文将详细介绍MathType的功能特点、操作步骤以…

Springboot校验集合是否为空,校验集合内对象参数

一、示例1 public AjaxResult saveQuoted(RequestBody NotEmpty List< Valid HisParam> list) {}二、示例2 public class Comment {NotNull(message "orderId 不能为空")private Long orderId;ValidNotEmpty(message "itemList不能为空")private…