文章目录
前言
今天受朋友邀请,来实现一个通讯录管理系统的开发,功能要求:具备完整的通讯录功能,包括新增、查找、显示、修改、删除、清空等基本功能,仔细思考了一下,感觉难度不算很大,只需要利用 C++ 的基本知识足已完成,此外,还可以扩展一些对错误的预处理功能,增强实用性。
在此基础上,还提出了一些其他的要求,比如函数需要份文件编写、利用函数实现功能分离、同样的功能必须用同一函数实现等等,这对我们的思路清晰程度还是有一定要求的,接下来,我们开始分析。
心急的话可以直接跳至结尾部分的完整代码,可以复制粘贴直接运行,查看运行效果。
一、思路分析
整个项目大致分为三个文件,contacts.h 存放头文件和联系人结构体以及全部函数的声明,contacts_function 用来存放全部的函数实现,contacts_main 用来存放 main 函数即可。实际上,很多项目都可以用这样的思路来对代码进行分文件编写。
我们首先来分析整个项目需要的全部功能,首先,输出供用户选择的菜单并读取用户的选项可以用一个函数来完成,新建、查找、显示、修改、删除、清空各用一个函数完成,其中许多功能都基于查找,如果要将这些功能整合为一个查找函数,那么此函数就需要一个额外的参数将功能分离,用以适应不同情况下的调用。
主函数只需要根据用户选择的功能调用对应的函数即可实现对应的功能。思路基本整理清楚,接下来,就根据当前思路开始尝试编写代码吧!
二、函数实现
1.联系人结构体
存储联系人的诸多信息,毫无疑问我们需要一个结构体数组,我们首先建立一个联系人结构体,包含联系人的姓名、性别、年龄、号码、地址信息。
代码如下:
struct contact
{
// 名字默认为“未定义”
string name = "未定义";
// 为方便存储,暂定:女 - 0,男 - 1
bool gender = 0;
int age = 0;
string phone_number;
string address;
};
2.菜单函数
菜单函数主要负责输出用户选择界面,并读入用户选择的功能,代码结构较为简单。
代码如下:
/* 输出菜单目录,供用户进行选择,返回钥匙 key */
int menu()
{
cout << "欢迎使用由 Alkaid#3529 开发的通讯录管理系统\n\n";
cout << "1.新建联系人\n";
cout << "2.显示联系人\n";
cout << "3.查找联系人\n";
cout << "4.修改联系人\n";
cout << "5.删除联系人\n";
cout << "6.清空联系人\n";
cout << "0.退出通讯录\n\n";
cout << "请选择您需要的功能: ";
int key = 0;
cin >> key;
return key;
}
3.新建联系人功能函数
这个函数负责在指定的位置添加联系人,因此需要对应的地址,从而修改对应内容。
代码如下:
/* 在指定位置添加联系人 */
void add_contact(contact* p_added)
{
// 对输入错误的预处理,如果指针为空,则判断用户输入错误,不操作
if (p_added == NULL)
{
system("pause");
system("cls");
return;
}
cout << "请输入联系人的姓名:";
cin >> p_added->name;
cout << "请输入联系人的性别(女-0 男-1):";
cin >> p_added->gender;
cout << "请输入联系人的年龄:";
cin >> p_added->age;
cout << "请输入联系人的联系电话:";
cin >> p_added->phone_number;
cout << "请输入联系人的地址:";
cin >> p_added->address;
cout << "保存成功!\n";
system("pause");
system("cls");
return;
}
4.显示联系人功能函数
考虑到显示联系人有两种请路况:一种是根据用户选择查找对应联系人并显示,另一种是显示通讯录中存储的全部联系人,因此需要额外的一个参数来控制函数状态,进行不同的输出。
代码如下:
/* 根据地址按照指定条件显示特定联系人 */
/* ord==0,依次展示所有联系人 */
/* ord==1,展示指定联系人 */
void display_contacts(contact* p_show, int ord)
{
// 对输入错误的预处理,如果指针为空,则判断用户输入错误,不操作
if (p_show == NULL)
{
system("pause");
system("cls");
return;
}
if (ord == 0)
{
for (int i = 0; p_show->name != "未定义"; i++)
{
cout << "第" << i + 1 << "名联系人为:\n";
cout << p_show->name << " " << p_show->gender << " " << p_show->age << " " << p_show->phone_number << " " << p_show->address << endl;
p_show++;
}
}
if (ord == 1)
{
cout << "您想要查看的联系人为:\n";
cout << p_show->name << " " << p_show->gender << " " << p_show->age << " " << p_show->phone_number << " " << p_show->address << endl;
}
system("pause");
system("cls");
return;
}
5.删除联系人功能函数
我们只需根据用户提供的联系人姓名找到存储该联系人的地址,对该处地址进行初始化即可。
代码如下:
/* 根据地址删除联系人 */
void delete_contact(contact* p_deleted)
{
if (p_deleted == NULL)
{
system("pause");
system("cls");
return;
}
p_deleted->name = "未定义";
cout << "删除成功!\n";
system("pause");
system("cls");
return;
}
5.修改联系人功能函数
修改联系人的操作较为简单,我们只需找到用户指定的联系人地址,对该地址的数据进行重新读入即可。
代码如下:
/* 根据地址修改联系人 */
void modify_contact(contact* p_modified)
{
if (p_modified == NULL)
{
system("pause");
system("cls");
return;
}
cout << "请输入修改后联系人的姓名:";
cin >> p_modified->name;
cout << "请输入修改后联系人的性别(女-0 男-1):";
cin >> p_modified->gender;
cout << "请输入修改后联系人的年龄:";
cin >> p_modified->age;
cout << "请输入修改后联系人的联系电话:";
cin >> p_modified->phone_number;
cout << "请输入修改后联系人的地址:";
cin >> p_modified->address;
cout << "修改成功!\n";
system("pause");
system("cls");
return;
}
6.清空联系人功能函数
只需要获取结构体数组的首地址,对全部数组进行初始化,即可完成清空通讯录。
代码如下:
/* 清空全部联系人 */
void empty_contact(contact* p_emptied)
{
for (int i = 0; p_emptied->name != "未定义"; i++)
{
p_emptied->name = "未定义";
p_emptied++;
}
cout << "已清空!\n";
system("pause");
system("cls");
return;
}
7.查找函数
查找函数作为许多功能函数的即使,在许多函数中发挥作用,因此我们同样利用一个指令参数对查找函数进行功能分类,以便查找不同条件下的对应地址。需要注意的是,查找函数的返回值是结构体数组的某一处地址,因此它可以直接作为一些功能函数的参数使用。
/* 查找指定条件的联系人位置,返回该位置的地址 */
/* ord==0,找到可供添加的位置 */
/* ord==1,根据名字找到需要删除的位置 */
/* ord==2,根据名字找到需要显示的位置 */
/* ord==3,根据名字找到需要修改的位置 */
contact* find(contact alkaid[100], int ord)
{
contact* p = alkaid;
string name_chosen = "未定义";
if (ord == 0)
{
for (int i = 0; alkaid[i].name != name_chosen; i++)
{
p++;
if (i == 99)
{
cout << "通讯录已满,请删除联系人\n";
p = NULL;
break;
}
}
}
if (ord == 1)
{
cout << "请输入你想删除的联系人的名字:";
cin >> name_chosen;
for (int i = 0; alkaid[i].name != name_chosen; i++)
{
p++;
if (i == 99)
{
cout << "未查询到需要删除的联系人\n";
p = NULL;
break;
}
}
}
if (ord == 2)
{
cout << "请输入你想查找的联系人的名字:";
cin >> name_chosen;
for (int i = 0; alkaid[i].name != name_chosen; i++)
{
p++;
if (i == 99)
{
cout << "未查询到需要查找的联系人\n";
p = NULL;
break;
}
}
}
if (ord == 3)
{
cout << "请输入你想修改的联系人的名字:";
cin >> name_chosen;
for (int i = 0; alkaid[i].name != name_chosen; i++)
{
p++;
if (i == 99)
{
cout << "未查询到需要修改的联系人\n";
p = NULL;
break;
}
}
}
return p;
}
8.主函数
在已经完成所有功能函数的基础上,秩序在主函数中调用对应的函数即可。
代码如下:
int main()
{
// alkaid 数组用于存放100名联系人的信息
contact alkaid[100];
// 打印菜单,为用户提供选项,用 key 表示用户选择的功能
int key = 0;
for (;;)
{
key = menu();
if (key == 1)
{
add_contact(find(alkaid, 0));
}
else if (key == 2)
{
display_contacts(alkaid, 0);
}
else if (key == 3)
{
display_contacts(find(alkaid, 2), 1);
}
else if (key == 4)
{
modify_contact(find(alkaid, 3));
}
else if (key == 5)
{
delete_contact(find(alkaid, 1));
}
else if (key == 6)
{
empty_contact(alkaid);
}
else if (key == 0)
{
break;
}
}
return 0;
}
三、完整代码
为了方便大家使用,我将代码整理到一个文件中,大家只需要复制粘贴运行就好,可以放心使用,此处就不展示运行结果了。
代码如下:
/* Alkaid#3529 */
#include<iostream>
#include<string>
#include<windows.h>
using namespace std;
struct contact
{
// 名字默认为“未定义”
string name = "未定义";
// 为方便存储,暂定:女 - 0,男 - 1
bool gender = 0;
int age = 0;
string phone_number;
string address;
};
/* 输出菜单目录,供用户进行选择,返回钥匙 key */
int menu();
/* 查找指定条件的联系人位置,返回该位置的地址 */
/* ord==0,找到可供添加的位置 */
/* ord==1,根据名字找到需要删除的位置 */
/* ord==2,根据名字找到需要显示的位置 */
/* ord==3,根据名字找到需要修改的位置 */
contact* find(contact alkaid[100], int ord);
/* 在指定位置添加联系人 */
void add_contact(contact* p_added);
/* 根据地址按照指定条件显示特定联系人 */
/* ord==0,依次展示所有联系人 */
/* ord==1,展示指定联系人 */
void display_contacts(contact* p_show, int ord);
/* 根据地址删除联系人 */
void delete_contact(contact* p_deleted);
/* 根据地址修改联系人 */
void modify_contact(contact* p_modified);
/* 清空全部联系人 */
void empty_contact(contact* p_emptied);
int main()
{
// alkaid 数组用于存放100名联系人的信息
contact alkaid[100];
// 打印菜单,为用户提供选项,用 key 表示用户选择的功能
int key = 0;
for (;;)
{
key = menu();
if (key == 1)
{
add_contact(find(alkaid, 0));
}
else if (key == 2)
{
display_contacts(alkaid, 0);
}
else if (key == 3)
{
display_contacts(find(alkaid, 2), 1);
}
else if (key == 4)
{
modify_contact(find(alkaid, 3));
}
else if (key == 5)
{
delete_contact(find(alkaid, 1));
}
else if (key == 6)
{
empty_contact(alkaid);
}
else if (key == 0)
{
break;
}
}
return 0;
}
int menu()
{
cout << "欢迎使用由 Alkaid#3529 开发的通讯录管理系统\n\n";
cout << "1.新建联系人\n";
cout << "2.显示联系人\n";
cout << "3.查找联系人\n";
cout << "4.修改联系人\n";
cout << "5.删除联系人\n";
cout << "6.清空联系人\n";
cout << "0.退出通讯录\n\n";
cout << "请选择您需要的功能: ";
int key = 0;
cin >> key;
return key;
}
contact* find(contact alkaid[100], int ord)
{
contact* p = alkaid;
string name_chosen = "未定义";
if (ord == 0)
{
for (int i = 0; alkaid[i].name != name_chosen; i++)
{
p++;
if (i == 99)
{
cout << "通讯录已满,请删除联系人\n";
p = NULL;
break;
}
}
}
if (ord == 1)
{
cout << "请输入你想删除的联系人的名字:";
cin >> name_chosen;
for (int i = 0; alkaid[i].name != name_chosen; i++)
{
p++;
if (i == 99)
{
cout << "未查询到需要删除的联系人\n";
p = NULL;
break;
}
}
}
if (ord == 2)
{
cout << "请输入你想查找的联系人的名字:";
cin >> name_chosen;
for (int i = 0; alkaid[i].name != name_chosen; i++)
{
p++;
if (i == 99)
{
cout << "未查询到需要查找的联系人\n";
p = NULL;
break;
}
}
}
if (ord == 3)
{
cout << "请输入你想修改的联系人的名字:";
cin >> name_chosen;
for (int i = 0; alkaid[i].name != name_chosen; i++)
{
p++;
if (i == 99)
{
cout << "未查询到需要修改的联系人\n";
p = NULL;
break;
}
}
}
return p;
}
void add_contact(contact* p_added)
{
// 对输入错误的预处理,如果指针为空,则判断用户输入错误,不操作
if (p_added == NULL)
{
system("pause");
system("cls");
return;
}
cout << "请输入联系人的姓名:";
cin >> p_added->name;
cout << "请输入联系人的性别(女-0 男-1):";
cin >> p_added->gender;
cout << "请输入联系人的年龄:";
cin >> p_added->age;
cout << "请输入联系人的联系电话:";
cin >> p_added->phone_number;
cout << "请输入联系人的地址:";
cin >> p_added->address;
cout << "保存成功!\n";
system("pause");
system("cls");
return;
}
void display_contacts(contact* p_show, int ord)
{
if (p_show == NULL)
{
system("pause");
system("cls");
return;
}
if (ord == 0)
{
for (int i = 0; p_show->name != "未定义"; i++)
{
cout << "第" << i + 1 << "名联系人为:\n";
cout << p_show->name << " " << p_show->gender << " " << p_show->age << " " << p_show->phone_number << " " << p_show->address << endl;
p_show++;
}
}
if (ord == 1)
{
cout << "您想要查看的联系人为:\n";
cout << p_show->name << " " << p_show->gender << " " << p_show->age << " " << p_show->phone_number << " " << p_show->address << endl;
}
system("pause");
system("cls");
return;
}
void delete_contact(contact* p_deleted)
{
if (p_deleted == NULL)
{
system("pause");
system("cls");
return;
}
p_deleted->name = "未定义";
cout << "删除成功!\n";
system("pause");
system("cls");
return;
}
void modify_contact(contact* p_modified)
{
if (p_modified == NULL)
{
system("pause");
system("cls");
return;
}
cout << "请输入修改后联系人的姓名:";
cin >> p_modified->name;
cout << "请输入修改后联系人的性别(女-0 男-1):";
cin >> p_modified->gender;
cout << "请输入修改后联系人的年龄:";
cin >> p_modified->age;
cout << "请输入修改后联系人的联系电话:";
cin >> p_modified->phone_number;
cout << "请输入修改后联系人的地址:";
cin >> p_modified->address;
cout << "修改成功!\n";
system("pause");
system("cls");
return;
}
void empty_contact(contact* p_emptied)
{
for (int i = 0; p_emptied->name != "未定义"; i++)
{
p_emptied->name = "未定义";
p_emptied++;
}
cout << "已清空!\n";
system("pause");
system("cls");
return;
}
总结
时间较为仓促,我也是第一次写这么长的博客,没有对这个通讯录管理系统进行更进一步的优化,也没来得及添加更详细的注释,还有许多点可以处理的更为合理,大家感兴趣的话我后续会更新一份更完整、清晰的代码。
开发这个系统也让我略费工夫,觉得不错的话不妨点个赞,谢谢大家啦!
最后我是Alkaid#3529,期待你的关注!