一、简介
本题要实现的功能有:
1.添加联系人。
2.显示联系人。
3.删除联系人。
4.查找联系人。
5.修改联系人。
6.清空通讯录。
0.退出通讯录。
二、思路
(注:代码中疑难问题在每一小段都有做解释,关于参数为什么采用地址传递,在第三部分有做解释。如果有其他问题我没有解释清楚的话,可以留言,我会补充进去。整合代码在第四部分,可以直接使用。)
首先我们要显示一个菜单,然后用户可以通过输入不同的数字进入相应的操作界面。写一个程序首先要写一个主函数,然后由易到难实现各个功能即可。接下来我们按次序依次实现。
2.0准备工作
在此之前,我们首先要创建一个联系人结构体,包含“姓名、性别、年龄、电话、住址”等信息;和一个通讯录结构体,包含一个联系人数组,以及通讯录中的人员个数。
注意,我在“性别”这一项使用的是 int 类型,用户只需要输入1或2就可以存储相应的性别。
//设计联系人结构体,包含姓名、性别、年龄、电话、住址
struct person {
string m_Name;
int m_Sex; //1.男 2.女
int m_Age;
string m_Phone;
string m_Addr;
};
//设计通讯录结构体
struct Addressbooks {
person personArray[MAX]; //通讯录中保存的联系人数组
int m_Size; //通讯录中人员个数
};
2.1主函数框架
实现功能:输入0-6不同的数字进入相应的操作界面进行操作。并且每次操作后都会回到菜单界面,方便进行下一次操作(这也就是为什么放在while循环里面并且条件一直为true)。
思路:我们首先想到用一个变量 select 接收用户输入的值,然后用 switch-case 语句实现一一对应的操作。
#include<iostream>
#include<string>
#define MAX 1000
using namespace std;
int main() {
int select = 0; //用户选择输入的值
Addressbooks abs; //创建一个通讯录变量abs并给它初始化一下
abs.m_Size = 0;
while (true) {
cin >> select; //输入
switch (select) {
case 0: //0. 退出通讯录
break;
case 1: //1. 添加联系人
break;
case 2: //2. 显示联系人
break;
case 3: //3. 删除联系人
break;
case 4: //4. 查找联系人
break;
case 5: //5. 修改联系人
break;
case 6: //6. 清空联系人
break;
}
}
2.2菜单showMenu()
用户见到的第一个界面一定是菜单栏,因此我们写一个菜单函数。
//显示菜单栏
void showMenu() {
printf("***********************\n");
printf("*** 1. 添加联系人 ***\n");
printf("*** 2. 显示联系人 ***\n");
printf("*** 3. 删除联系人 ***\n");
printf("*** 4. 查找联系人 ***\n");
printf("*** 5. 修改联系人 ***\n");
printf("*** 6. 清空通讯录 ***\n");
printf("*** 0. 退出通讯录 ***\n");
printf("***********************\n");
}
2.3退出通讯录
退出通讯录的操作很简单,我们只需要在用户输入0之后,屏幕上显示“欢迎下次使用”,然后退出程序即可。
case 0: //0. 退出通讯录
cout << "欢迎下次使用" << endl;
system("pause"); //请按任意键继续
return 0;
break;
2.4添加联系人
实现功能:用户输入1之后,进入“添加联系人”界面,然后根据系统提示依次输入“姓名、性别、年龄、电话、住址”等信息。
注意:当通讯录人满时,提示“通讯录已满,无法添加!”;当用户输入错误时(比如输入性别时输入了除1和2之外的其他数字)要有提示“输入有误,请重试!”;当用户输入结束后,提示“添加成功!”,然后清屏。
//1.添加联系人
void addPerson(Addressbooks* abs) { //因为参数是地址,所以用指针接收
//判断通讯录是否已满
if (abs->m_Size == MAX) {
cout << "通讯录已满,无法添加!" << endl;
return;
}
else {
//添加姓名
string name;
cout << "请输入姓名:";
cin >> name;
abs->personArray[abs->m_Size].m_Name = name; //把name存进去
//添加性别
cout << "请输入性别:" << endl;
cout << "1.男 2.女" << endl;
int sex;
while (true) {
cin >> sex;
if (sex == 1) {
abs->personArray[abs->m_Size].m_Sex = "男";
break;
}
else if (sex == 2) {
abs->personArray[abs->m_Size].m_Sex = "女";
break;
}
else {
cout << "输入有误,请重试!" << endl;
}
}
//添加年龄
cout << "请输入年龄:";
int age;
cin >> age;
abs->personArray[abs->m_Size].m_Age = age;
//添加电话
cout << "请输入电话:";
string phone;
cin >> phone;
abs->personArray[abs->m_Size].m_Phone = phone;
//添加住址
cout << "请添加住址:";
string addr;
cin >> addr;
abs->personArray[abs->m_Size].m_Addr = addr;
//更新通讯录人数
abs->m_Size++;
cout << "添加成功!" << endl;
system("pause");
system("cls"); //清屏操作
}
}
2.5显示联系人
实现功能:用户输入2之后,可以在一行中显示所有联系人的信息(如果一个联系人的信息显示5行,会很冗杂)。
注意:我们使用循环遍历输出,要检测通讯录中人数是否为0,如果为0则提示“记录为空!”,否则就显示联系人信息。查询结束后要做清屏操作。
//2.显示联系人
void showPerson(Addressbooks* abs) {
//判断通讯录中人数是否为0。若为0则提示记录为空,否则显示联系人信息
if (abs->m_Size == 0) {
cout << "当前记录为空!" << endl;
}
else {
for (int i = 0; i < abs->m_Size; i++) {
cout << "姓名:" << abs->personArray[i].m_Name << "\t";
cout << "性别:" << abs->personArray[i].m_Sex << "\t";
cout << "年龄:" << abs->personArray[i].m_Age << "\t";
cout << "电话:" << abs->personArray[i].m_Phone << "\t";
cout << "住址:" << abs->personArray[i].m_Addr << endl;
}
}
//查询完成后清屏
system("pause");
system("cls");
}
2.6删除联系人
实现功能:用户输入3之后进入删除联系人的界面,继而根据提示输入要删除的人的姓名,然后系统删除该联系人的全部信息。
思路:我们要删除某个联系人,首先我们要找到这个联系人,于是我们就需要根据用户输入的姓名来找到这个联系人在联系人数组中的下标。所以我们在实现删除操作之前,要实现一个查找联系人下标的函数 isExist() 。
注意:要判断该联系人是否在通讯录中。查询结束后要做清屏操作。
//检测联系人是否存在,如果存在,返回联系人在数组中的位置,不存在返回-1
int isExist(Addressbooks* abs, string name) {
for (int i = 0; i < abs->m_Size; i++) {
if (abs->personArray[i].m_Name == name) {
return i;
}
}
return -1;
}
//3.删除联系人
void deletePerson(Addressbooks* abs) {
cout << "请输入你要删除的联系人的姓名:";
string name;
cin >> name;
int ret = isExist(abs, name);
if ( ret == -1) {
cout << "查无此人!" << endl;
}
else { //查找到之后进行删除操作
abs->personArray[ret] = abs->personArray[abs->m_Size - 1]; //最后一个人的信息覆盖删除的人的信息
abs->m_Size--;
cout << "删除成功!" << endl;
}
system("pause");
system("cls");
}
2.7查找联系人
实现功能:用户输入4之后进入查找联系人的界面,然后根据提示输入要查找的联系人的姓名,系统找到该联系人并显示其相关的所有信息。
注意:要判断该联系人是否在通讯录中。查询结束后要做清屏操作。
//4.查找联系人
void findPerson(Addressbooks* abs) {
cout << "请输入您要查找的联系人:";
string name;
cin >> name;
//判断该联系人是否存在通讯录中
int ret = isExist(abs, name);
if (ret != -1) { //找到
cout << "姓名:" << abs->personArray[ret].m_Name << "\t";
cout << "性别:" << abs->personArray[ret].m_Sex << "\t";
cout << "年龄:" << abs->personArray[ret].m_Age << "\t";
cout << "电话:" << abs->personArray[ret].m_Phone << "\t";
cout << "住址:" << abs->personArray[ret].m_Addr << endl;
}
else {
cout << "查无此人!" << endl;
}
system("pause");
system("cls");
}
2.8修改联系人
实现功能:用户输入5之后,进入修改联系人的界面。然后根据提示输入要修改的联系人的姓名;然后提示用户要修改什么信息(性别一般不做修改),根据提示修改完成后提示“修改成功!”。如果没有这个人就提示“查无此人!”。
//5.修改联系人
void modifyPerson(Addressbooks* abs) {
cout << "请输入您要修改的联系人:";
string name;
cin >> name;
int ret = isExist(abs, name);
if (ret != -1) {
int s; //存放要进行的操作
cout << "请选择要修改的信息:" << endl;
cout << "1.姓名 2.年龄 3.电话 4.住址" << endl;
cin >> s;
switch (s) {
case 1: {
cout << "请输入修改后的姓名:";
string nname;
cin >> nname;
abs->personArray[ret].m_Name = nname;
break;
}
case 2: {
cout << "请输入修改后的年龄:";
int nage;
cin >> nage;
abs->personArray[ret].m_Age = nage;
break;
}
case 3: {
cout << "请输入修改后的电话:";
string nphone;
cin >> nphone;
abs->personArray[ret].m_Phone = nphone;
break;
}
case 4: {
cout << "请输入修改后的住址:";
string nadd;
cin >> nadd;
abs->personArray[ret].m_Addr = nadd;
break;
}
}
cout << "修改成功!" << endl;
}
else {
cout << "查无此人!" << endl;
}
system("pause");
system("cls");
}
2.9清空通讯录
实现功能:用户输入6之后,先提示用户“是否真的要清空通讯录”,如果用户选择“是”,就清空通讯录;否则返回菜单界面。
//6.清空通讯录
void cleanPerson(Addressbooks* abs) {
int a;
cout<<"是否确定要清空通讯录?"<<endl;
cout<<"是: 1 否: 2" <<endl;
cin>>a;
if(a==1){
abs->m_Size = 0;
cout << "通讯录已清空!" << endl;
}
system("pause");
system("cls");
}
2.10整理main函数
我们已经把所有用到的操作用函数封装起来了,现在只需要把main函数添加上对应的操作就可以完成程序。
int main() {
int select = 0; //用户选择输入的值
Addressbooks abs; //创建一个通讯录变量abs并给它初始化一下
abs.m_Size = 0;
while (true) {
showMenu();
cin >> select;
switch (select) {
case 0: //0. 退出通讯录
cout << "欢迎下次使用" << endl;
system("pause"); //请按任意键继续
return 0;
break;
case 1: //1. 添加联系人
addPerson(&abs); //添加联系人的操作函数,传参要使用地址传递,这样可以修改实参的值
break;
case 2: //2. 显示联系人
showPerson(&abs);
break;
case 3: //3. 删除联系人
deletePerson(&abs);
break;
case 4: //4. 查找联系人
findPerson(&abs);
break;
case 5: //5. 修改联系人
modifyPerson(&abs);
break;
case 6: //6. 清空联系人
cleanPerson(&abs);
break;
}
}
三、问题小结
我们注意到在所有的case语句中的函数传参时,我们用的都是地址传递,因为这样可以修改实参的值。否则如果我们使用值传递,那就会出现我们在函数内部大搞一通,出来之后发现什么也没变的情况。
四、代码整合
#include<iostream>
#include<string>
#define MAX 1000
using namespace std;
//设计联系人结构体,包含姓名、性别、年龄、电话、住址
struct person {
string m_Name;
int m_Sex; //1.男 2.女
int m_Age;
string m_Phone;
string m_Addr;
};
//设计通讯录结构体
struct Addressbooks {
person personArray[MAX]; //通讯录中保存的联系人数组
int m_Size; //通讯录中人员个数
};
//显示菜单栏
void showMenu() {
printf("***********************\n");
printf("*** 1. 添加联系人 ***\n");
printf("*** 2. 显示联系人 ***\n");
printf("*** 3. 删除联系人 ***\n");
printf("*** 4. 查找联系人 ***\n");
printf("*** 5. 修改联系人 ***\n");
printf("*** 6. 清空通讯录 ***\n");
printf("*** 0. 退出通讯录 ***\n");
printf("***********************\n");
}
//1.添加联系人
void addPerson(Addressbooks* abs) { //因为参数是地址,所以用指针接收
//判断通讯录是否已满
if (abs->m_Size == MAX) {
cout << "通讯录已满,无法添加!" << endl;
return;
}
else {
//添加姓名
string name;
cout << "请输入姓名:";
cin >> name;
abs->personArray[abs->m_Size].m_Name = name; //把name存进去
//添加性别
cout << "请输入性别:" << endl;
cout << "1.男 2.女" << endl;
int sex;
while (true) {
cin >> sex;
if (sex == 1) {
abs->personArray[abs->m_Size].m_Sex = "男";
break;
}
else if (sex == 2) {
abs->personArray[abs->m_Size].m_Sex = "女";
break;
}
else {
cout << "输入有误,请重试!" << endl;
}
}
//添加年龄
cout << "请输入年龄:";
int age;
cin >> age;
abs->personArray[abs->m_Size].m_Age = age;
//添加电话
cout << "请输入电话:";
string phone;
cin >> phone;
abs->personArray[abs->m_Size].m_Phone = phone;
//添加住址
cout << "请添加住址:";
string addr;
cin >> addr;
abs->personArray[abs->m_Size].m_Addr = addr;
//更新通讯录人数
abs->m_Size++;
cout << "添加成功!" << endl;
system("pause");
system("cls"); //清屏操作
}
}
//2.显示联系人
void showPerson(Addressbooks* abs) {
//判断通讯录中人数是否为0。若为0则提示记录为空,否则显示联系人信息
if (abs->m_Size == 0) {
cout << "当前记录为空!" << endl;
}
else {
for (int i = 0; i < abs->m_Size; i++) {
cout << "姓名:" << abs->personArray[i].m_Name << "\t";
cout << "性别:" << abs->personArray[i].m_Sex << "\t";
cout << "年龄:" << abs->personArray[i].m_Age << "\t";
cout << "电话:" << abs->personArray[i].m_Phone << "\t";
cout << "住址:" << abs->personArray[i].m_Addr << endl;
}
}
//查询完成后清屏
system("pause");
system("cls");
}
//检测联系人是否存在,如果存在,返回联系人在数组中的位置,不存在返回-1
int isExist(Addressbooks* abs, string name) {
for (int i = 0; i < abs->m_Size; i++) {
if (abs->personArray[i].m_Name == name) {
return i;
}
}
return -1;
}
//3.删除联系人
void deletePerson(Addressbooks* abs) {
cout << "请输入你要删除的联系人的姓名:";
string name;
cin >> name;
int ret = isExist(abs, name);
if ( ret == -1) {
cout << "查无此人!" << endl;
}
else { //查找到之后进行删除操作
abs->personArray[ret] = abs->personArray[abs->m_Size - 1]; //最后一个人的信息覆盖删除的人的信息
abs->m_Size--;
cout << "删除成功!" << endl;
}
system("pause");
system("cls");
}
//4.查找联系人
void findPerson(Addressbooks* abs) {
cout << "请输入您要查找的联系人:";
string name;
cin >> name;
//判断该联系人是否存在通讯录中
int ret = isExist(abs, name);
if (ret != -1) { //找到
cout << "姓名:" << abs->personArray[ret].m_Name << "\t";
cout << "性别:" << abs->personArray[ret].m_Sex << "\t";
cout << "年龄:" << abs->personArray[ret].m_Age << "\t";
cout << "电话:" << abs->personArray[ret].m_Phone << "\t";
cout << "住址:" << abs->personArray[ret].m_Addr << endl;
}
else {
cout << "查无此人!" << endl;
}
system("pause");
system("cls");
}
//5.修改联系人
void modifyPerson(Addressbooks* abs) {
cout << "请输入您要修改的联系人:";
string name;
cin >> name;
int ret = isExist(abs, name);
if (ret != -1) {
int s; //存放要进行的操作
cout << "请选择要修改的信息:" << endl;
cout << "1.姓名 2.年龄 3.电话 4.住址" << endl;
cin >> s;
switch (s) {
case 1: {
cout << "请输入修改后的姓名:";
string nname;
cin >> nname;
abs->personArray[ret].m_Name = nname;
break;
}
case 2: {
cout << "请输入修改后的年龄:";
int nage;
cin >> nage;
abs->personArray[ret].m_Age = nage;
break;
}
case 3: {
cout << "请输入修改后的电话:";
string nphone;
cin >> nphone;
abs->personArray[ret].m_Phone = nphone;
break;
}
case 4: {
cout << "请输入修改后的住址:";
string nadd;
cin >> nadd;
abs->personArray[ret].m_Addr = nadd;
break;
}
}
cout << "修改成功!" << endl;
}
else {
cout << "查无此人!" << endl;
}
system("pause");
system("cls");
}
//6.清空通讯录
void cleanPerson(Addressbooks* abs) {
int a;
cout<<"是否确定要清空通讯录?"<<endl;
cout<<"是: 1 否: 2" <<endl;
cin>>a;
if(a==1){
abs->m_Size = 0;
cout << "通讯录已清空!" << endl;
}
system("pause");
system("cls");
}
int main() {
int select = 0; //用户选择输入的值
Addressbooks abs; //创建一个通讯录变量abs并给它初始化一下
abs.m_Size = 0;
while (true) {
showMenu();
cin >> select;
switch (select) {
case 0: //0. 退出通讯录
cout << "欢迎下次使用" << endl;
system("pause"); //请按任意键继续
return 0;
break;
case 1: //1. 添加联系人
addPerson(&abs); //添加联系人的操作函数,传参要使用地址传递,这样可以修改实参的值
break;
case 2: //2. 显示联系人
showPerson(&abs);
break;
case 3: //3. 删除联系人
deletePerson(&abs);
break;
case 4: //4. 查找联系人
findPerson(&abs);
break;
case 5: //5. 修改联系人
modifyPerson(&abs);
break;
case 6: //6. 清空联系人
cleanPerson(&abs);
break;
}
}
return 0;
}