通讯录管理系统(C++)
前言
本程序采用VS2019开发实现
博主尽可能完善并健壮了程序功能,如有不理想之处,请加以指正,博主会在第一时间修改完善。原创不易,望"推荐","关注","收藏","转发",谢谢!!!
代码
点击查看代码
#include<iostream>
#include<string>
#include<regex>
using namespace std;
#define MAX 10
// 联系人结构体
struct Person {
// 姓名
string m_name;
// 性别 1--男;2--女
int m_sex = 0;
// 年龄
int m_age = 0;
// 电话号码
string m_phoneNum;
// 地址
string m_Address;
};
// 通讯录结构体
struct AddressBook {
// 通讯录中保存联系人的数组
struct Person person[MAX];
// 通讯录中当前联系人的个数
int m_Size = 0;
};
// 正则表达式匹配
bool match(string input, string express) {
// 匹配结果存放声明
smatch results;
regex pattern(express);
return regex_search(input, results, pattern);
}
// 判断姓名
bool jugeName(AddressBook* abs, string name) {
bool ret = match(name, "^([\xa1-\xff]{4,8}(@[\xa1-\xff]{4,8}){0,11})$|^([A-Z][a-z]{2,27}( [A-Z][a-z]{2,27}){0,11})$");
if (abs->m_Size == 0) {
if (ret) return true;
else return false;
}else {
if (ret) {
for (int i = 0; i < abs->m_Size; i++) {
if (abs->person[i].m_name._Equal(name)) return false;
}
}
}
return true;
}
// 判断电话号码
bool jugePhoneNum(AddressBook* abs, string phoneNum) {
bool ret = match(phoneNum, "^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])[0-9]{8}$");
if (abs->m_Size == 0) {
if (ret) return true;
else return false;
}
else {
if (ret) {
for (int i = 0; i < abs->m_Size; i++) {
if (abs->person[i].m_phoneNum._Equal(phoneNum)) return false;
}
}
}
return true;
}
// 判断年龄
bool jugeAge(string age) {
if (match(age, "^([7-9]|[1-9][0-9]|1[01][0-9]|1[23]0)$")) return true;
return false;
}
// 判断性别
bool jugeSex(string sex) {
if (match(sex, "^([12])$")) return true;
return false;
}
// 判断地址信息
bool jugeAddress(string address) {
if (match(address, "^([^省]+省|.+自治区|[^市]+市)([^自治州]+自治州|[^市]+市|[^县]+县|[^区]+区|[^盟]+盟|[^地区]+地区|.+区划)([^市]+市|[^镇]+镇|[^县]+县|[^旗]+旗|.+区)$")) return true;
return false;
}
// 判断联系人是否存在(存在返回下标,不存在返回-1)
int IsExist(const AddressBook* const abs, string name) {
for (int i = 0; i < abs->m_Size; i++) {
// 找到用户输入的姓名了
if (abs->person[i].m_name._Equal(name)) {
return i;
}
}
return -1;
}
// 错误信息
void ErrorMessage() {
cout << "输入格式不合理,请按要求重新输入..." << endl << endl;
}
// 显示具体联系人信息
void showSpecificPersonMessage(struct Person person) {
setlocale(LC_ALL, "Zh-Hans"); // 地域设置
wchar_t nameChar[2] = L"·";
cout << "姓名:";
for (unsigned int i = 0; i < person.m_name.length(); i++) {
if (person.m_name[i] == '@') wcout << nameChar[0];
else cout << person.m_name[i];
}
cout<< "\t\t性别:" << (person.m_sex == 1 ? "男" : "女")
<< "\t年龄:" << person.m_age
<< "\t电话号码:" << person.m_phoneNum
<< "\t地址:" << person.m_Address << endl << endl;
}
// 功能:健壮姓名的输入
bool formatName(AddressBook* abs, int Num) {
while (true) {
string name;
cout << "请输入目标姓名(如需停止输入,请输入\"q\"):";
getline(cin, name);
if (!name._Equal("q")) {
if (jugeName(abs, name)) {
abs->person[Num].m_name = name;
cout << "该姓名可以录入..." << endl << endl;
break;
}
if (abs->m_Size == 0) ErrorMessage();
else cout << "存在该姓名,不能录入..." << endl << endl;
}else return false;
}
return true;
}
// 功能:健壮性别的输入
void formatSex(AddressBook* abs, int Num) {
string sex;
while (true) {
cout << "请输入目标性别(格式:1--男 2--女):";
getline(cin, sex);
if (jugeSex(sex)) {
abs->person[Num].m_sex = atoi(sex.c_str());
break;
}
ErrorMessage();
}
}
// 功能:健壮年龄输入
void formatAge(AddressBook* abs, int Num) {
while (true) {
string age;
cout << "请输入目标年龄:";
getline(cin, age);
if (jugeAge(age)) {
abs->person[Num].m_age = atoi(age.c_str());
break;
}
ErrorMessage();
}
}
// 功能:健壮电话号码输入
bool formatePhoneNum(AddressBook* abs, int Num) {
while (true) {
string phoneNum;
cout << "请输入目标电话号码(如需停止输入,请输入\"q\"):";
getline(cin, phoneNum);
if (!phoneNum._Equal("q")) {
if (jugePhoneNum(abs, phoneNum)) {
abs->person[Num].m_phoneNum = phoneNum;
cout << "该电话号码可以录入..." << endl << endl;
break;
}
if (abs->m_Size == 0) ErrorMessage();
else cout << "存在该电话号码,不能录入..." << endl << endl;
}else return false;
}
return true;
}
// 功能:健壮地址信息输入
void formateAddress(AddressBook* abs, int Num) {
while (true) {
string address;
cout << "请输入目标地址信息:";
getline(cin, address);
if (jugeAddress(address)) {
abs->person[Num].m_Address = address;
break;
}
ErrorMessage();
}
}
// 功能:健壮输入信息
bool formatInputMessage(AddressBook* abs) {
// 姓名
bool ret1 = formatName(abs, abs->m_Size);
if (ret1) {
// 性别
formatSex(abs, abs->m_Size);
// 年龄
formatAge(abs, abs->m_Size);
}else return false;
// 电话号码
bool ret2 = formatePhoneNum(abs, abs->m_Size);
if (ret2) {
// 地址
formateAddress(abs, abs->m_Size);
}else return false;
return true;
}
// 1.添加联系人
void addPerson(AddressBook* abs) {
// 判断通讯录是否已满,如果满了就不再添加
if (abs->m_Size == MAX) {
cout << "通讯录已满,请删除不常用的联系人后重新添加..." << endl;
return;
}else {
// 添加具体的联系人信息
bool ret = formatInputMessage(abs);
if (ret){
abs->m_Size++;
cout << "添加成功..." << endl << endl;
}else cout << "添加失败..." << endl << endl;
}
}
// 2.显示联系人
void showPerson(const AddressBook * const abs) {
if (abs->m_Size == 0) cout << "当前记录为空..." << endl << endl;
else {
cout << "所有联系人信息如下:" << endl << endl;
for (int i = 0; i < abs->m_Size; i++) {
showSpecificPersonMessage(abs->person[i]);
}
}
}
// 3.删除联系人
bool deletePerson(AddressBook *abs, string name){
int ret = IsExist(abs, name);
if (ret != -1) {
cout << "存在该联系人..." << endl;
for (int i = ret; i < abs->m_Size; i++) {
abs->person[i] = abs->person[i + 1];
}
abs->m_Size--;
}else {
cout << "查无此人..." << endl;
return false;
}
return true;
}
// 4.查找联系人
void findByName(const AddressBook* const abs, string name) {
int ret = IsExist(abs, name);
if (ret != -1) {
cout << endl;
cout << "存在该联系人,信息如下..." << endl;
showSpecificPersonMessage(abs->person[ret]);
}else {
cout << "查无此人..." << endl;
}
}
// 封装修改函数
void modifyPersonInner(AddressBook* abs, int ret) {
cout << "联系人信息包含以下几项:" << endl;
cout << "1.姓名\t2.性别\t3.年龄\t4.电话号码\t5.地址" << endl << "注意:输入数字0则保存修改信息并返回主菜单..." << endl << endl;
while (true){
string Num;
cout << "请输入要修改信息的数字编号:";
getline(cin, Num);
if (Num._Equal("1")) {
formatName(abs, ret);
}else if (Num._Equal("2")) {
formatSex(abs, ret);
}else if (Num._Equal("3")) {
formatAge(abs, ret);
}else if (Num._Equal("4")) {
formatePhoneNum(abs, ret);
}else if (Num._Equal("5")) {
formateAddress(abs, ret);
}else if (Num._Equal("0")) {
cout << "修改成功..." << endl << endl;
cout << "修改后的信息如下:" << endl;
showSpecificPersonMessage(abs->person[ret]);
break;
}else ErrorMessage();
}
}
// 5.修改联系人
void modifyPersonOuter(AddressBook* abs, string name) {
int ret = IsExist(abs, name);
if (ret != -1) {
cout << endl;
cout << "存在该联系人,信息如下..." << endl;
showSpecificPersonMessage(abs->person[ret]);
cout << endl;
cout << "********** 进入修改页面 ************" << endl;
modifyPersonInner(abs, ret);
}
else {
cout << "查无此人..." << endl;
}
}
// 6.清空联系人
void clearAll(AddressBook *abs) {
if (abs->m_Size == 0) return;
while (true) {
string SURE;
cout << "确定要清空通讯录吗?(Y/N):";
getline(cin, SURE);
if (SURE.length() == 1) {
if (SURE._Equal("y") || SURE._Equal("Y")) {
cout << "您选择YES,请稍等..." << endl;
abs->m_Size = 0;
cout << "记录清空成功..." << endl << endl;
break;
}else if (SURE._Equal("N") || SURE._Equal("n")) {
cout << "您选择NO, 请稍等..." << endl << endl;
break;
}
}
ErrorMessage();
}
}
// 显示菜单
void showMenu() {
cout << "**********************" << endl;
cout << "**** 1.添加联系人 ****" << endl;
cout << "**** 2.显示联系人 ****" << endl;
cout << "**** 3.删除联系人 ****" << endl;
cout << "**** 4.查找联系人 ****" << endl;
cout << "**** 5.修改联系人 ****" << endl;
cout << "**** 6.清空联系人 ****" << endl;
cout << "**** 0.退出通讯录 ****" << endl;
cout << "**********************" << endl;
cout << "注意:\n1.姓名不能重复且只能输入 [@,空格] 两种特殊字符,如姓名中有[·],请以[@]代替\n" << "2.性别:1--男,2--女\n"
<< "3.手机号码不能重复且需符合国家规定\n"
<< "4.年龄为 7 - 130 之间的整数\n" << "5.地址信息:标准的 [省市区,市区镇,市县镇]...\n\n";
}
int main() {
// 创建通讯录结构体变量
AddressBook abs;
while (true) {
showMenu();
// 输入通讯录的功能编号
string Num;
while (true) {
cout << "请输入选择的功能编号:";
getline(cin, Num);
if (match(Num, "^([0-6])$")) break;
ErrorMessage();
}
switch (atoi(Num.c_str())) {
case 1: // 1.添加联系人
{
addPerson(&abs); // 利用地址传递可以修改实参
showPerson(&abs);
system("pause");
system("cls");
}
break;
case 2: // 2.显示联系人
{
showPerson(&abs);
system("pause");
system("cls");
}
break;
case 3: // 3.删除联系人
{
if (abs.m_Size != 0) {
string name;
cout << "请输入要删除的联系人姓名:";
getline(cin, name);
bool ret = deletePerson(&abs, name);
if (ret == true) {
cout << "删除成功..." << endl << endl;
showPerson(&abs);
}else {
cout << "删除失败..." << endl << endl;
}
}else cout << "当前记录为空..." << endl << endl;
system("pause");
system("cls");
}
break;
case 4: // 4.查找联系人
{
if (abs.m_Size != 0) {
string name;
cout << "请输入要查找的联系人姓名:";
getline(cin, name);
findByName(&abs, name);
}else cout << "当前记录为空..." << endl << endl;
system("pause");
system("cls");
}
break;
case 5: // 5.修改联系人
{
showPerson(&abs);
if (abs.m_Size != 0) {
string name;
cout << "请输入要修改的联系人姓名:";
getline(cin, name);
modifyPersonOuter(&abs, name);
}
system("pause");
system("cls");
}
break;
case 6: // 6.清空联系人
{
clearAll(&abs);
showPerson(&abs);
cout << "正在返回主菜单, ";
system("pause");
system("cls");
}
break;
case 0: // 0.退出通讯录
cout << "欢迎下次使用..." << endl;
system("pause");
return 0;
break;
}
}
return 0;
}
通讯录管理系统(C++)的更多相关文章
- iOS学习之Object-C语言简单的通讯录管理系统
用这几天学的OC的知识,写了一个实现简单功能的通讯录管理系统,在这里分享给大家: 通讯录管理系统 * 需求: 1.定义联系人类Contact.实例变量:姓名(拼音,首字母大写).性别.电话号码.住址 ...
- c语言实现通讯录管理系统(c课程设计)
工具:Visual C++6.0 说明: 本系统基于C语言实现班级通讯录管理系统,为大一时学习C语言刚入门所做的课程设计.功能包括增.删.查.改等,非常适合初学者练手.通讯录包括的个人信息有姓名.学号 ...
- c++实现通讯录管理系统(控制台版)
c++实现通讯录管理系统(控制台版) 此项目适合c++初学者,针对c++基础知识,涉及到变量.结构体定义使用.数组定义使用.指针定义使用等. 运行之后的结果如下: 代码: #include <i ...
- C++入门-控制台版的通讯录管理系统
通讯录管理系统 1.系统需求 通讯录是一个可以记录亲人.好友信息的工具. 本教程主要利用C++来实现一个通讯录管理系统 系统中需要实现的功能如下: 添加联系人:向通讯录中添加新人,信息包括(姓名.性别 ...
- C++课程设计 通讯录管理系统 原码及解析
设计题目:通信录管理系统 用C++设计出模拟手机通信录管理系统,实现对手机中的通信录进行管理. (一)功能要求 查看功能:选择此功能时,列出下列三类选择. A 办公类B 个人类C 商务类,当选中某类时 ...
- C++通讯录管理系统(添加联系人,显示联系人,删除联系人,查找联系人,修改联系人,清空联系人,退出通讯录)
1 /** 2 * ProjectNmae:通讯录管理系统 3 * 功能: 4 * 添加联系人:向通讯录添加新人 5 * 显示联系人:显示通讯录中的所有联系人信息 6 * 删除联系人:按照姓名进行删除 ...
- c++—通讯录管理系统
一.运用所学的结构体.地址指针等基础知识,完成通讯录管理系统 二.系统主要有以下6个功能: 1.添加联系人2.显示联系人 3.删除联系人 4.查找联系人5.修改联系人 6.清空联系人 1 #inclu ...
- C语言通讯录管理系统
本文转载自:http://blog.csdn.net/hackbuteer1/article/details/6573488 实现了通讯录的录入信息.保存信息.插入.删除.排序.查找.单个显示等功能. ...
- 通讯录管理系统(C语言)
/* * 对通讯录进行插入.删除.排序.查找.单个显示功能 */ #include <stdio.h> #include <malloc.h> #include <str ...
- c++实例之通讯录管理系统之清空联系人功能(七)
#include<iostream> using namespace std; constexpr auto MAX = ; //联系人结构体 struct Person { string ...
随机推荐
- 第3届云原生技术实践峰会(CNBPS 2020)重磅开启,“原”力蓄势待发!
CNBPS 2020将在11月19-21日全新启动!作为国内最有影响力的云原生盛会之一,云原生技术实践峰会(CNBPS)至今已举办三届. 在2019年的CNBPS上,灵雀云CTO陈恺喊出"云 ...
- Elasticsearch基础知识学习
概要 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java开发的,并作为Ap ...
- 常用Cron表达式范例
描述 表达式 每隔5秒执行一次 */5 * * * * ? 每隔1分钟执行一次 0 */1 * * * ? 每天23点执行一次 0 0 23 * * ? 每天凌晨1点执行一次 0 0 1 * * ? ...
- EF4中多表关联查询Include的写法
大家好,好久没有写作了,最近遇到了个问题,最终是靠自己的尝试写出来的,希望可以帮到有需要的人. 在我们查询时通常会遇到多级表关联的情况,很多时候有人会想写一个from LINQ语句来解决,那么冗长的代 ...
- 品味Spring Cache设计之美
最近负责教育类产品的架构工作,两位研发同学建议:"团队封装的Redis客户端可否适配Spring Cache,这样加缓存就会方便多了" . 于是边查阅文档边实战,收获颇丰,写这篇文 ...
- [Windows]为windows系统鼠标右键添加软件和图标
转载自 https://blog.csdn.net/p312011150/article/details/81207059 一.打开注册表 首先打开windows的注册表,当然了,我个人倾向于 (1) ...
- eclipse导入项目jdk版本不一样
一:eclipse导入项目jdk版本不一样解决方案 参考博文: https://www.cnblogs.com/chenmingjun/p/8472885.html 选中项目右键 --> Pro ...
- golang gin框架中实现一个简单的不是特别精确的秒级限流器
起因 看了两篇关于golang中限流器的帖子: Gin 开发实践:如何实现限流中间件 常用限流策略--漏桶与令牌桶介绍 我照着用,居然没效果-- 时间有限没有深究.这实在是一个很简单的功能,我的需求是 ...
- 【Kafka】基于Windows环境的Kafka有关环境(scala+zookeeper+kafka+可视化工具)搭建、以及使用.NET环境开发的案例代码与演示
前言:基于Windows系统下的Kafka环境搭建:以及使用.NET 6环境进行开发简单的生产者与消费者的演示. 一.环境部署 Kafka是使用Java语言和Scala语言开发的,所以需要有对应的Ja ...
- Qt之QFontDialog
widget.h: #ifndef WIDGET_H #define WIDGET_H #include <QWidget> class Widget : public QWidget { ...