从0到1入门C++编程——02 通讯录管理系统

文章目录

  • 一、创建结构体及菜单显示
  • 二、添加联系人
  • 三、显示联系人
  • 四、删除联系人
  • 五、查找联系人
  • 六、修改联系人
  • 七、清空联系人
  • 八、退出通讯录


本文通过C++实现一个通讯录管理系统,系统要实现的功能如下。
1、添加联系人:向通讯录中添加新人,信息包括(姓名、性别、年龄、联系电话、家庭住址)最多记录1000人;
2、显示联系人:显示通讯录中所有联系人信息;
3、删除联系人:按照姓名进行删除指定联系人;
4、查找联系人:按照姓名查看指定联系人信息;
5、修改联系人:按照姓名重新修改指定联系人;
6、清空联系人:清空通讯录中所有信息;
7、退出通讯录:退出当前使用的通讯录。


一、创建结构体及菜单显示

在实现这个管理系统时,需要创建结构体存放不同类型的数据。
每个联系人的结构体中存放姓名、性别、年龄、联系电话和家庭住址信息,结构体如下。

struct users  //用户结构体
{string name;int sex;   //1--男 0--女int age;string number;string address;
};

通讯录结构体就是所有用户的集合,此外还要加上一个计数的整型变量,用于计算目前存放的联系人数量。

struct ContactBook  //通讯录结构体
{struct users user[MAX];int user_num;
};

菜单显示功能在程序运行后就打印菜单,以供用户输入选择进行某项操作。
菜单显示的函数如下,只在里面完成打印即可。

void show_menu()
{cout <<"*****************************"<<endl;cout <<"******  1、添加联系人  ******"<<endl;cout <<"******  2、显示联系人  ******"<<endl;cout <<"******  3、删除联系人  ******"<<endl;cout <<"******  4、查找联系人  ******"<<endl;cout <<"******  5、修改联系人  ******"<<endl;cout <<"******  6、清空联系人  ******"<<endl;cout <<"******  7、退出通讯录  ******"<<endl;cout <<"*****************************"<<endl;
}

在主函数中调用菜单显示函数,运行程序之后如下所示,这会让执行的操作更加清楚。
在这里插入图片描述


二、添加联系人

在程序运行之后,用户输入1按下回车就要进行添加联系人的操作,添加联系人之前首先要判断通讯录是否已经存满,如果没有存满,就根据通讯录结构体中user_num作为数组下标开始添加联系人,并在添加完成之后将user_num加1,更新存放的联系人数量。
添加联系人的函数实现如下,注意函数参数的传递是通讯录结构体的地址传递,这样在函数中做的修改才能得以体现,后面的函数也是这样。

void add_user(ContactBook *p)
{if(p->user_num == MAX)cout<<"通讯录已满,无法添加新联系人!"<<endl;else{cout<<"输入联系人姓名:";cin>>p->user[p->user_num].name;int sex = 0;while(1){cout<<"输入联系人性别(1--男 0--女):";cin>>sex;if(sex == 0 || sex == 1){p->user[p->user_num].sex = sex;break;}cout<<"格式输入有误,重新输入(1--男 0--女)"<<endl;}int age = 0;while(1){cout<<"输入联系人年龄:";cin>>age;if(age >= 0 && age <= 150){p->user[p->user_num].age = age;break;}cout<<"年龄输入有误,重新输入!"<<endl;}cout<<"输入联系人电话:";cin>>p->user[p->user_num].number;cout<<"输入联系人地址:";cin>>p->user[p->user_num].address;p->user_num ++;}cout<<"添加联系人成功!"<<endl;system("pause");    //按任意键继续system("cls");    //清屏
}

程序运行后添加联系人的过程如下图所示。
在这里插入图片描述


三、显示联系人

在程序运行之后,用户输入2按下回车就要进行显示联系人的操作,显示联系人的过程比较简单,首先判断通讯录的user_num成员是否为0,为0表示通讯录为空,打印提示信息,否则就将存放的所有联系人信息打印。
显示联系人的函数实现如下。

void show_user(ContactBook *p)
{if(p->user_num == 0)cout<<"通讯录为空!"<<endl;else{cout<<"姓名\t"<<"性别\t"<<"年龄\t"<<"电话\t"<<"\t地址\t"<<endl;for(int i=0;i<p->user_num;i++){cout<<p->user[i].name<<"\t";/*if(p->user[i].sex == 1)cout<<"男\t";elsecout<<"女\t";*/cout<<(p->user[i].sex == 1 ? "男":"女")<<"\t";cout<<p->user[i].age<<"\t";cout<<p->user[i].number<<"\t";cout<<p->user[i].address<<"\t"<<endl;}}system("pause");    //按任意键继续system("cls");    //清屏
}

显示所有联系人的信息如下图所示。
在这里插入图片描述
如果没有联系人就提示通讯录为空。
在这里插入图片描述


四、删除联系人

删除、查找、修改都要用到存放联系人的数组下标,因此单独写一个函数用来得到这个索引。
user_index函数根据用户名进行查找,如果找到则返回存放的数组下标,没有找到就返回-1。

int user_index(ContactBook *p,string name)
{if(p->user_num == 0)cout<<"通讯录为空!"<<endl;else{for(int i=0;i<p->user_num;i++){if(p->user[i].name == name)return i;}return -1;}
}

在程序运行之后,用户输入3按下回车就要进行删除联系人的操作,删除联系人的函数如下,在里面调用user_index()函数返回下标值,根据下标值判断删除的用户是否存在,删除之后,当前位置之后的数据都要向前移动一位。

void delete_user(ContactBook *p)
{string name;int index = -1;cout <<"请输入要删除的联系人姓名:";cin >> name;index = user_index(p,name);if(index == -1)cout<<"要删除的联系人不存在!"<<endl;else{for(int i=index;i<p->user_num-1;i++){p->user[i] = p->user[i+1];  //通讯录中存放的数据前移}p->user_num--;  //通讯录中人数减1cout<<"删除联系人成功!"<<endl;}system("pause");    //按任意键继续system("cls");    //清屏
}

已经添加了a和b两个联系人,下面删除掉用户名为b的联系人。
在这里插入图片描述
删除之后再显示联系人,发现联系人b已经被删除了。
在这里插入图片描述


五、查找联系人

在程序运行之后,用户输入4按下回车就要进行查找联系人的操作,根据要查找的联系人姓名查找,如果要查找的信息存在就进行打印,不存在就打印提示信息。

void find_user(ContactBook *p)
{string name;int index = -1;cout <<"请输入要查找的联系人姓名:";cin >> name;index = user_index(p,name);if(index == -1)cout<<"要查找的联系人不存在!"<<endl;else{cout<<"姓名:"<<p->user[index].name<<"\t";cout<<"性别:"<<(p->user[index].sex == 1 ? "男":"女")<<"\t";cout<<"年龄:"<<p->user[index].age<<"\t";cout<<"电话:"<<p->user[index].number<<"\t";cout<<"地址:"<<p->user[index].address<<"\t"<<endl;}system("pause");    //按任意键继续system("cls");    //清屏
}

联系人存在打印的信息如下。
在这里插入图片描述
联系人不存在的情况打印如下。
在这里插入图片描述


六、修改联系人

在程序运行之后,用户输入5按下回车就要进行修改联系人的操作,修改联系人这里先写了一个函数用来显示需要修改的项,根据用户的输入决定要修改的条目。

void show_item()
{cout <<"*****************************"<<endl;cout <<"*******  1、修改姓名  *******"<<endl;cout <<"*******  2、修改性别  *******"<<endl;cout <<"*******  3、修改年龄  *******"<<endl;cout <<"*******  4、修改电话  *******"<<endl;cout <<"*******  5、修改地址  *******"<<endl;cout <<"*******  6、修改完成  *******"<<endl;cout <<"*****************************"<<endl;
}

修改联系人的函数如下,同样根据联系人的用户名判断要修改的用户是否存在,如果存在就选择要修改的项目,根据选择的项目修改对应的内容。

void modify_user(ContactBook *p)
{string name;int index = -1;cout <<"请输入要修改的联系人姓名:";cin >> name;index = user_index(p,name);if(index == -1)cout<<"要修改的联系人不存在!"<<endl;else{int item = -1;while(1){show_item();cout<<"输入要操作的条目编号:";cin>>item;switch(item){case 1: cout<<"输入修改后联系人姓名:";cin>>p->user[index].name;break;case 2: {cout<<"输入修改后联系人性别(1--男 0--女):";int sex = -1;while(1){cin>>sex;if(sex == 0 || sex == 1){p->user[index].sex = sex;break;}cout<<"格式输入有误,重新输入(1--男 0--女)"<<endl;}break;}case 3:{cout<<"输入修改后联系人年龄:";int age = 0;while(1){cin>>age;if(age >= 0 && age <= 150){p->user[index].age = age;break;}cout<<"年龄输入有误,重新输入!"<<endl;}break;}case 4:cout<<"输入修改后联系人电话:"<<endl;cin>>p->user[index].number;break;case 5:cout<<"输入修改后联系人地址:"<<endl;cin>>p->user[index].address;break;case 6:cout<<"修改联系人信息成功!"<<endl;break;default:cout<<"请正确的输入要操作的条目编号!"<<endl;}if(item == 6)break;}}system("pause");    //按任意键继续system("cls");    //清屏
}

修改的过程如下图所示。
在这里插入图片描述
修改后再显示联系人如下,信息就被修改成功了。
在这里插入图片描述


七、清空联系人

在程序运行之后,用户输入6按下回车就要进行清空联系人的操作,清空联系人的操作没必要将所有的数据清空,只需要将通讯录结构体中的计数成员user_num清零即可。

void clear_user(ContactBook *p)
{int x;cout<<"是否要清空通讯录?(1--是,0--否)";cin>>x;if(x == 1){p->user_num = 0; //作逻辑清空即可,没必要删除所有数据cout<<"通讯录已清空!"<<endl;}system("pause");    //按任意键继续system("cls");    //清屏
}

清空的过程中还会询问是否清空,如下图所示。
在这里插入图片描述
再次显示联系人,显示通讯录为空!
在这里插入图片描述


八、退出通讯录

退出通讯录在主函数中实现,主函数及头文件的内容如下。

#include <iostream>
#include <string>
using namespace std;
#define MAX 1000int main()
{ContactBook book;  book.user_num = 0;  //初始化通讯录人数为0while(1){show_menu();int select;cout <<"输入要操作的项目编号:";cin >> select;switch(select){case 1: add_user(&book);break;case 2: show_user(&book);break;case 3: delete_user(&book);break;case 4: find_user(&book);break;case 5: modify_user(&book);break;case 6: clear_user(&book);break;case 7: system("pause");  //按任意键继续return 0;default: system("cls");    //清屏cout <<"请正确的输入要操作的项目编号!"<<endl;}}system("pause");return 0;
}

当输入7的时候就return 0,按下回车后就退出了程序。
在这里插入图片描述


本文参考视频:
黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/590147.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Lightroom Classic 2024 for Mac/win中文版:摄影后期处理的极致体验

随着数字摄影的普及&#xff0c;后期处理成为创作过程中的关键环节。对于摄影师而言&#xff0c;一款强大的后期处理软件是必不可少的。Adobe Lightroom Classic 2024正是这样一款备受推崇的软件&#xff0c;它为摄影师提供了从导入、编辑到共享的一站式解决方案&#xff0c;让…

数据结构期末复习(3)栈和队列

堆栈&#xff08;stack&#xff09; 堆栈&#xff08;stack&#xff09;是一种基于后进先出&#xff08;LIFO&#xff0c;Last In First Out&#xff09;原则的数据结构。它模拟了现实生活中的堆栈&#xff0c;类似于一摞盘子或一堆书。 堆栈有两个基本操作&#xff1a;入栈&a…

2.3物理层下面的传输媒体

目录 2.3物理层下面的传输媒体2.3.1导引型传输媒体1.双绞线2.同轴电缆3.光纤 2.3.2非导引型传输媒体无线电微波通信 2.3物理层下面的传输媒体 传输媒体是数据传输系统中在发送器和接收器之间的物理通路 两大类&#xff1a; 导引型传输媒体&#xff1a;电磁波被导引沿着固体媒体…

开放原子训练营(第四季)TobudOS——TobudOS内核移植(keil版)

前言 12月份参加了开放原第四季线下活动&#xff0c;觉得很有意义。通过这篇博文&#xff0c;记录一下这次活动进行的移植TobudOS内核的过程&#xff0c;下面就让我们开始吧。 开发板介绍 本次使用的开发板型号为STM32H750&#xff0c;当然了&#xff0c;其他型号的开发版也…

Angular进阶之六:Progressive rendering

简介 Progressive Rendering 是一种提高 Web 应用性能的方法&#xff0c;允许页面在加载过程中逐步呈现&#xff0c;以提高用户体验。在本文中&#xff0c;我们将探讨如何在 Angular 中通过自定义指令实现 Progressive Rendering&#xff0c;特别是处理从服务器获取大量数据的…

Java开发过程中的幂等性问题

幂等性问题&#xff1a; 1. 有时我们在填写某些 form表单 时&#xff0c;保存按钮不小心快速点了两次&#xff0c;表中竟然产生了两条重复的数据&#xff0c;只是id不一样。 2. 我们在项目中为了解决 接口超时 问题&#xff0c;通常会引入了 重试机制 。第一次请求接口超时了…

【揭秘】如何使用LinkedHashMap来实现一个LUR缓存?

LRU&#xff08;Least Recently Used&#xff09;缓存是一种常用的缓存淘汰策略&#xff0c;用于在有限的缓存空间中存储数据。其基本思想是&#xff1a;如果数据最近被访问过&#xff0c;那么在未来它被访问的概率也更高。因此&#xff0c;LRU缓存会保留最近访问过的数据&…

Python编程新技能:如何优雅地实现水仙花数?

水仙花数&#xff08;Narcissistic number&#xff09;也被称为阿姆斯特朗数&#xff08;Armstrong number&#xff09;或自恋数等&#xff0c;它是一个非负整数&#xff0c;其特性是该数的每个位上的数字的n次幂之和等于它本身&#xff0c;其中n是该数的位数。简单来说&#x…

00-开篇导读:学习分库分表开源框架的正确方法

1 前言 互联网高速发展带来海量的信息化数据&#xff0c;也带来更多的技术挑战。各种智能终端设备&#xff08;比如摄像头或车载设备等&#xff09;以每天千万级的数据量上报业务数据&#xff0c;电商、社交等互联网行业更不必说。这样量级的数据处理&#xff0c;已经远不是传…

SELinux 安全模型——MLS

首发公号&#xff1a;Rand_cs BLP 模型&#xff1a;于1973年被提出&#xff0c;是一种模拟军事安全策略的计算机访问控制模型&#xff0c;它是最早也是最常用的一种多级访问控制模型&#xff0c;主要用于保证系统信息的机密性&#xff0c;是第一个严格形式化的安全模型 暂时无…

机器学习三要素与拟合问题

1.如何构建机器学习模型&#xff1f; 机器学习工作流程总结 1.获取数据 2.数据基本处理 3.特征工程 4.机器学习(模型训练) 5.模型评估 结果达到要求&#xff0c;上线服务&#xff0c;没有达到要求&#xff0c;重新上面步骤 我们使用机器学习监督学习分类预测模型的工作流…

Qt5 安装教程 - 跳过登录界面

Qt5 安装教程 - 跳过登录界面 引言一、下载二、安装三、使用四、修改、维护、卸载 引言 Qt5.14.2及以前的版本有离线安装包&#xff0c;无需登录 (老版本连登录界面也无)。之后的版本需登录进行在线安装。 本文以Qt5.12.2版本为例&#xff0c;说明如何跳过登录界面&#xff0c…

Android Context在四大组件及Application中的表现

文章目录 Android Context在四大组件及Application中的表现Context是什么Context源码Activity流程分析Service流程分析BroadcastReceiver流程分析ContentProvider流程分析Application流程分析 Android Context在四大组件及Application中的表现 Context是什么 Context可以理解…

Java技术栈 —— Redis的雪崩、穿透与击穿

Java技术栈 —— Redis的雪崩、穿透与击穿 〇、实验的先导条件&#xff08;NginxJmeter&#xff09;一、Redis缓存雪崩、缓存穿透、缓存击穿1.1 雪崩1.2 穿透1.3 击穿 二、Redis应用场景——高并发2.1 单机部署的高并发问题与解决&#xff08;JVM级别锁&#xff09;2.2 集群部署…

Redis7.2.3(Windows版本)

1、解压 &#xfeff; &#xfeff; 2、设置密码 &#xff08;1&#xff09; 右击编辑redis.conf文件&#xff1a; &#xfeff; &#xff08;2&#xff09; 设置密码。 &#xfeff; 3、测试密码是否添加成功 &#xfeff; 如上图所示&#xff0c;即为成功。 4、设置…

spring创建与使用

spring创建与使用 创建 Spring 项⽬创建⼀个 Maven 项⽬添加 Spring 框架⽀持添加启动类 存储 Bean 对象创建 Bean将 Bean 注册到容器 获取并使⽤ Bean 对象创建 Spring 上下⽂获取指定的 Bean 对象获取bean对象的方法 使⽤ Bean 总结 创建 Spring 项⽬ 接下来使⽤ Maven ⽅式…

010、切片

除了引用&#xff0c;Rust还有另外一种不持有所有权的数据类型&#xff1a;切片&#xff08;slice&#xff09;。切片允许我们引用集合中某一段连续的元素序列&#xff0c;而不是整个集合。 考虑这样一个小问题&#xff1a;编写一个搜索函数&#xff0c;它接收字符串作为参数&a…

12.29最小生成数K算法复习(注意输入输出格式),校园最短路径(通过PRE实现路径输出,以及输入输出格式注意)

7-2 最小生成树-kruskal算法 分数 15 const int maxn 1000; struct edge {int u, v, w; }e[maxn]; int n, m, f[30]; bool cmp(edge a, edge b) {return a.w < b.w; } int find(int x) {if (f[x] x) {return x;}else {f[x] find(f[x]);return f[x];} } //int arr[100…

vue脚手架安装

1、安装&#xff1a; npm i vue/cli -g(-g全局安装,全名global) vue --version 查看版本号 2、使用 vue create 项目名称 3、安装选择项 最后一个选N

【Redis-03】Redis数据结构与对象原理 -下篇

承接上篇【Redis-02】Redis数据结构与对象原理 -上篇 8. type-字符串string 8.1 字符串的三种encoding编码&#xff08;int embstr raw&#xff09; 如果保存的是整型&#xff0c;并且可以用long类型标识&#xff08;-9223372036854775808到9223372036854775807&#xff09…