目录
最近在B站看了黑马程序员的C++视频,第一阶段的大作业是写一个通讯录管理系统,在这里做个记录。相对于原视频,增加了一个恢复联系人的功能
前期准备
首先封装一个showMenu函数,作用是显示菜单,向用户展示通讯录具备的功能
//显示菜单
void showMenu()
{
cout << "****************************" << endl;
cout << "******* 1-添加联系人 *******" << endl;
cout << "******* 2-显示联系人 *******" << endl;
cout << "******* 3-删除联系人 *******" << endl;
cout << "******* 4-查找联系人 *******" << endl;
cout << "******* 5-修改联系人 *******" << endl;
cout << "******* 6-清空联系人 *******" << endl;
cout << "******* 7-恢复联系人 *******" << endl;
cout << "******* 0-退出通讯录 *******" << endl;
cout << "****************************" << endl;
}
然后需要定义两个结构体
//定义联系人结构体
struct person //既然结构体也是一种数据类型,那么首字母就像int、string一样小写好了
{
string name;
string sex;
int age;
string phone;
string address;
};
//定义通讯录结构体
struct addressBooks //后续取名字都这样算了,第一次单词小写,第二个单词大写
{
person personArray[MAX]; //联系人个数的上限为MAX,这样做的目的是方便后期维护
int size = 0; //通讯录中当前联系人个数
};
下面开始写功能
一、添加联系人
//添加联系人
void addPerson(addressBooks* aBs)
{
//先判断通讯录是否已满,如果满了就提示用户
if (aBs->size == MAX)
{
cout << "通讯录已满" << endl;
}
//如果没满就开始添加
else
{
int index = aBs->size; //初始值为0
//输入姓名
cout << "\n"; //空行
string name;
cout << "姓名:";
cin >> name;
aBs->personArray[index].name = name; //储存
//输入性别
cout << "\n";
string sex;
cout << "性别:";
cin >> sex;
aBs->personArray[index].sex = sex; //储存
//输入年龄
cout << "\n";
int age;
cout << "年龄:";
while (true) //无限循环
{
cin >> age;
//输入的年龄大于0并且小于150才储存,并跳出循环
if (150 > age > 0)
{
aBs->personArray[index].age = age; //储存
break; //这里的break的作用是跳出while循环,对if-else语句不起作用
}
//否则就重新输入
else
{
cout << "请重新输入:";
}
}
//输入电话
cout << "\n";
string phone;
cout << "电话:";
cin >> phone;
aBs->personArray[index].phone = phone; //储存
//输入住址
cout << "\n";
string address;
cout << "住址:";
cin >> address;
aBs->personArray[index].address = address; //储存
aBs->size++; //每添加一个联系人,size就加1
cout << "\n";
cout << "添加成功!" << endl;
cout << "\n";
system("pause"); //打印“请按任意键继续”,等待用户输入任意键后再执行清屏代码,让用户看一看自己输入的信息后再清屏
system("cls"); //清屏
}
}
二、显示联系人
//显示联系人
void showPerson(addressBooks* aBs)
{
//先判断通讯录中是否存在联系人
if (aBs->size == 0)
{
cout << "\n";
cout << "当前通讯录中尚无联系人!" << endl;
cout << "\n";
}
//存在联系人的话就执行打印操作
else
{
for (int i = 0; i < aBs->size; i++)
{
cout << "\n";
cout << "姓名:" << aBs->personArray[i].name << "\t"; //制表符\t的机制到底是什么???“制表符代表八个空格”的说法是错误的
cout << "性别:" << aBs->personArray[i].sex << "\t";
cout << "年龄:" << aBs->personArray[i].age << "\t";
cout << "电话:" << aBs->personArray[i].phone << "\t";
cout << "住址:" << aBs->personArray[i].address << endl;
cout << "\n";
}
}
system("pause"); //打印“请按任意键继续”,等待用户输入任意键后再执行清屏代码,让用户看一看输出的信息后再清屏
system("cls"); //清屏
}
三、删除联系人
//删除联系人
void deletePerson(addressBooks* aBs)
{
cout << "\n";
cout << "您要删除的联系人是:";
string name;
cin >> name;
int index = -1;
//遍历通讯录,找到要删除的联系人在通讯录中的位置
for (int i = 0; i < aBs->size; i++)
{
if (aBs->personArray[i].name == name)
{
index = i; //储存联系人在通讯录(数组)中的位置
break;
}
}
if (index == -1) //index还是-1,说明没找到
{
cout << "\n";
cout << "查无此人" << endl;
cout << "\n";
}
else //找到了,那就把他删除
{
//联系人信息逐个向前覆盖,相当于删除了第一个被覆盖的联系人
for (index; index < aBs->size; index++)
{
aBs->personArray[index] = aBs->personArray[index + 1];
}
aBs->size--; //每删除一个联系人,size就减1
cout << "\n";
cout << "删除成功!" << endl;
cout << "\n";
}
system("pause"); //打印“请按任意键继续”,等待用户输入任意键后再执行清屏代码
system("cls"); //清屏
}
四、查找联系人
//查找联系人
void findPerson(addressBooks* aBs)
{
cout << "\n";
cout << "您要查找的联系人是:";
string name;
cin >> name;
int index = -1;
//遍历通讯录,找到联系人在通讯录中的位置
for (int i = 0; i < aBs->size; i++)
{
if (aBs->personArray[i].name == name)
{
index = i; //储存联系人在通讯录(数组)中的位置
break;
}
}
if (index == -1) //index还是-1,说明没找到
{
cout << "\n";
cout << "查无此人" << endl;
cout << "\n";
}
else //找到了,那就把他的信息打印
{
cout << "\n";
cout << "姓名:" << aBs->personArray[index].name << "\t"; //制表符\t的机制到底是什么???“制表符代表八个空格”的说法是错误的
cout << "性别:" << aBs->personArray[index].sex << "\t";
cout << "年龄:" << aBs->personArray[index].age << "\t";
cout << "电话:" << aBs->personArray[index].phone << "\t";
cout << "住址:" << aBs->personArray[index].address << endl;
cout << "\n";
}
system("pause"); //打印“请按任意键继续”,等待用户输入任意键后再执行清屏代码
system("cls"); //清屏
}
五、修改联系人
//修改联系人
void modifyPerson(addressBooks* aBs)
{
cout << "\n";
cout << "您要修改的联系人是:";
string name;
cin >> name;
int index = -1;
//遍历通讯录,找到联系人在通讯录中的位置
for (int i = 0; i < aBs->size; i++)
{
if (aBs->personArray[i].name == name)
{
index = i; //储存联系人在通讯录(数组)中的位置
break;
}
}
if (index == -1) //index还是-1,说明没找到
{
cout << "\n";
cout << "查无此人" << endl;
cout << "\n";
}
else //找到了,那就把他的信息修改
{
//输入姓名
cout << "\n"; //空行
string name;
cout << "姓名:";
cin >> name;
aBs->personArray[index].name = name; //储存
//输入性别
cout << "\n";
string sex;
cout << "性别:";
cin >> sex;
aBs->personArray[index].sex = sex; //储存
//输入年龄
cout << "\n";
int age;
cout << "年龄:";
while (true) //无限循环
{
cin >> age;
//输入的年龄大于0并且小于150才储存,并跳出循环
if (150 > age > 0)
{
aBs->personArray[index].age = age; //储存
break; //这里的break的作用是跳出while循环,对if-else语句不起作用
}
//否则就重新输入
else
{
cout << "请重新输入:";
}
}
//输入电话
cout << "\n";
string phone;
cout << "电话:";
cin >> phone;
aBs->personArray[index].phone = phone; //储存
//输入住址
cout << "\n";
string address;
cout << "住址:";
cin >> address;
aBs->personArray[index].address = address; //储存
cout << "\n";
cout << "修改成功!" << endl;
cout << "\n";
}
system("pause"); //打印“请按任意键继续”,等待用户输入任意键后再执行清屏代码
system("cls"); //清屏
}
六、清空联系人
//清空联系人
void cleanPerson(addressBooks* aBs)
{
aBs->size = 0;
cout << "\n";
cout << "清空成功!" << endl;
cout << "\n";
system("pause"); //打印“请按任意键继续”,等待用户输入任意键后再执行清屏代码
system("cls"); //清屏
}
七、恢复联系人
//恢复联系人
void recoveryPerson(addressBooks* aBs)
{
for (int i = 0; i < MAX; i++)
{
if (aBs->personArray[i].age > 0) //未赋值的数组元素中的age,在内存默认保存为-858993460
{
aBs->size = i + 1;
}
else
{
cout << "\n";
cout << "恢复成功!" << endl;
cout << "\n";
system("pause"); //打印“请按任意键继续”,等待用户输入任意键后再执行清屏代码
system("cls"); //清屏
break;
}
}
}
完整代码
/*
本来是想把函数都分文件编写的,但是对于需要用到自定义结构体的函数,
在对应的cpp文件里还得把结构体的定义都粘贴过去,很麻烦,而且代码反而更冗余了,遂放弃
*/
#include<iostream>
#define MAX 10//设置得太大的话,main函数那里会警告“函数使用了堆栈的“XXXXXX”个字节 : 超过了 / analyze : stacksize '16384'。 请考虑将某些数据移到堆中。"
using namespace std;
//定义联系人结构体
struct person //既然结构体也是一种数据类型,那么首字母就像int、string一样小写好了
{
string name;
string sex;
int age;
string phone;
string address;
};
//定义通讯录结构体
struct addressBooks //后续取名字都这样算了,第一次单词小写,第二个单词大写
{
person personArray[MAX]; //联系人个数的上限为MAX,这样做的目的是方便后期维护
int size = 0; //通讯录中当前联系人个数
};
//显示菜单
void showMenu()
{
cout << "****************************" << endl;
cout << "******* 1-添加联系人 *******" << endl;
cout << "******* 2-显示联系人 *******" << endl;
cout << "******* 3-删除联系人 *******" << endl;
cout << "******* 4-查找联系人 *******" << endl;
cout << "******* 5-修改联系人 *******" << endl;
cout << "******* 6-清空联系人 *******" << endl;
cout << "******* 7-恢复联系人 *******" << endl;
cout << "******* 0-退出通讯录 *******" << endl;
cout << "****************************" << endl;
}
//添加联系人
void addPerson(addressBooks* aBs)
{
//先判断通讯录是否已满,如果满了就提示用户
if (aBs->size == MAX)
{
cout << "通讯录已满" << endl;
}
//如果没满就开始添加
else
{
int index = aBs->size; //初始值为0
//输入姓名
cout << "\n"; //空行
string name;
cout << "姓名:";
cin >> name;
aBs->personArray[index].name = name; //储存
//输入性别
cout << "\n";
string sex;
cout << "性别:";
cin >> sex;
aBs->personArray[index].sex = sex; //储存
//输入年龄
cout << "\n";
int age;
cout << "年龄:";
while (true) //无限循环
{
cin >> age;
//输入的年龄大于0并且小于150才储存,并跳出循环
if (150 > age > 0)
{
aBs->personArray[index].age = age; //储存
break; //这里的break的作用是跳出while循环,对if-else语句不起作用
}
//否则就重新输入
else
{
cout << "请重新输入:";
}
}
//输入电话
cout << "\n";
string phone;
cout << "电话:";
cin >> phone;
aBs->personArray[index].phone = phone; //储存
//输入住址
cout << "\n";
string address;
cout << "住址:";
cin >> address;
aBs->personArray[index].address = address; //储存
aBs->size++; //每添加一个联系人,size就加1
cout << "\n";
cout << "添加成功!" << endl;
cout << "\n";
system("pause"); //打印“请按任意键继续”,等待用户输入任意键后再执行清屏代码,让用户看一看自己输入的信息后再清屏
system("cls"); //清屏
}
}
//显示联系人
void showPerson(addressBooks* aBs)
{
//先判断通讯录中是否存在联系人
if (aBs->size == 0)
{
cout << "\n";
cout << "当前通讯录中尚无联系人!" << endl;
cout << "\n";
}
//存在联系人的话就执行打印操作
else
{
for (int i = 0; i < aBs->size; i++)
{
cout << "\n";
cout << "姓名:" << aBs->personArray[i].name << "\t"; //制表符\t的机制到底是什么???“制表符代表八个空格”的说法是错误的
cout << "性别:" << aBs->personArray[i].sex << "\t";
cout << "年龄:" << aBs->personArray[i].age << "\t";
cout << "电话:" << aBs->personArray[i].phone << "\t";
cout << "住址:" << aBs->personArray[i].address << endl;
cout << "\n";
}
}
system("pause"); //打印“请按任意键继续”,等待用户输入任意键后再执行清屏代码,让用户看一看输出的信息后再清屏
system("cls"); //清屏
}
//删除联系人
void deletePerson(addressBooks* aBs)
{
cout << "\n";
cout << "您要删除的联系人是:";
string name;
cin >> name;
int index = -1;
//遍历通讯录,找到要删除的联系人在通讯录中的位置
for (int i = 0; i < aBs->size; i++)
{
if (aBs->personArray[i].name == name)
{
index = i; //储存联系人在通讯录(数组)中的位置
break;
}
}
if (index == -1) //index还是-1,说明没找到
{
cout << "\n";
cout << "查无此人" << endl;
cout << "\n";
}
else //找到了,那就把他删除
{
//联系人信息逐个向前覆盖,相当于删除了第一个被覆盖的联系人
for (index; index < aBs->size; index++)
{
aBs->personArray[index] = aBs->personArray[index + 1];
}
aBs->size--; //每删除一个联系人,size就减1
cout << "\n";
cout << "删除成功!" << endl;
cout << "\n";
}
system("pause"); //打印“请按任意键继续”,等待用户输入任意键后再执行清屏代码
system("cls"); //清屏
}
//查找联系人
void findPerson(addressBooks* aBs)
{
cout << "\n";
cout << "您要查找的联系人是:";
string name;
cin >> name;
int index = -1;
//遍历通讯录,找到联系人在通讯录中的位置
for (int i = 0; i < aBs->size; i++)
{
if (aBs->personArray[i].name == name)
{
index = i; //储存联系人在通讯录(数组)中的位置
break;
}
}
if (index == -1) //index还是-1,说明没找到
{
cout << "\n";
cout << "查无此人" << endl;
cout << "\n";
}
else //找到了,那就把他的信息打印
{
cout << "\n";
cout << "姓名:" << aBs->personArray[index].name << "\t"; //制表符\t的机制到底是什么???“制表符代表八个空格”的说法是错误的
cout << "性别:" << aBs->personArray[index].sex << "\t";
cout << "年龄:" << aBs->personArray[index].age << "\t";
cout << "电话:" << aBs->personArray[index].phone << "\t";
cout << "住址:" << aBs->personArray[index].address << endl;
cout << "\n";
}
system("pause"); //打印“请按任意键继续”,等待用户输入任意键后再执行清屏代码
system("cls"); //清屏
}
//修改联系人
void modifyPerson(addressBooks* aBs)
{
cout << "\n";
cout << "您要修改的联系人是:";
string name;
cin >> name;
int index = -1;
//遍历通讯录,找到联系人在通讯录中的位置
for (int i = 0; i < aBs->size; i++)
{
if (aBs->personArray[i].name == name)
{
index = i; //储存联系人在通讯录(数组)中的位置
break;
}
}
if (index == -1) //index还是-1,说明没找到
{
cout << "\n";
cout << "查无此人" << endl;
cout << "\n";
}
else //找到了,那就把他的信息修改
{
//输入姓名
cout << "\n"; //空行
string name;
cout << "姓名:";
cin >> name;
aBs->personArray[index].name = name; //储存
//输入性别
cout << "\n";
string sex;
cout << "性别:";
cin >> sex;
aBs->personArray[index].sex = sex; //储存
//输入年龄
cout << "\n";
int age;
cout << "年龄:";
while (true) //无限循环
{
cin >> age;
//输入的年龄大于0并且小于150才储存,并跳出循环
if (150 > age > 0)
{
aBs->personArray[index].age = age; //储存
break; //这里的break的作用是跳出while循环,对if-else语句不起作用
}
//否则就重新输入
else
{
cout << "请重新输入:";
}
}
//输入电话
cout << "\n";
string phone;
cout << "电话:";
cin >> phone;
aBs->personArray[index].phone = phone; //储存
//输入住址
cout << "\n";
string address;
cout << "住址:";
cin >> address;
aBs->personArray[index].address = address; //储存
cout << "\n";
cout << "修改成功!" << endl;
cout << "\n";
}
system("pause"); //打印“请按任意键继续”,等待用户输入任意键后再执行清屏代码
system("cls"); //清屏
}
//清空联系人
void cleanPerson(addressBooks* aBs)
{
aBs->size = 0;
cout << "\n";
cout << "清空成功!" << endl;
cout << "\n";
system("pause"); //打印“请按任意键继续”,等待用户输入任意键后再执行清屏代码
system("cls"); //清屏
}
//恢复联系人
void recoveryPerson(addressBooks* aBs)
{
for (int i = 0; i < MAX; i++)
{
if (aBs->personArray[i].age > 0) //未赋值的数组元素中的age,在内存默认保存为-858993460
{
aBs->size = i + 1;
}
else
{
cout << "\n";
cout << "恢复成功!" << endl;
cout << "\n";
system("pause"); //打印“请按任意键继续”,等待用户输入任意键后再执行清屏代码
system("cls"); //清屏
break;
}
}
}
//主函数
int main()
{
addressBooks aBs; //创建通讯录
aBs.size = 0; //通讯录刚创建,联系人个数是0
while (true) //无限循环
{
showMenu(); //不加括号就调用不了
cout << "\n";
cout << "请输入您的选择:";
int select;
cin >> select;
switch (select)
{
case 1: //添加联系人
addPerson(&aBs); //一定要用地址传递,不然无法修改实参,在函数里添加了再多联系人信息也是白干
break;
case 2: //显示联系人
showPerson(&aBs);
break;
case 3: //删除联系人
deletePerson(&aBs);
break;
case 4: //查找联系人
findPerson(&aBs);
break;
case 5: //修改联系人
modifyPerson(&aBs);
break;
case 6: //清空联系人
cleanPerson(&aBs);
break;
case 7: //恢复联系人
recoveryPerson(&aBs);
break;
case 0: //退出通讯录
cout << "\n";
cout << "欢迎下次使用!" << endl;
exit(0); //退出整个程序,或者用return 0;
//break; //在这里用break语句只能跳出switch语句,无法跳出while循环,更无法退出整个程序。在这里得用return语句或者exit语句退出整个程序
default:
break;
}
}
}