通讯录管理系统

1.系统需求

  • 添加联系人
  • 查找联系人
  • 显示联系人
  • 删除联系人
  • 修改联系人
  • 清空通讯录
  • 推出通讯录

2.菜单功能

1
2
3
4
5
6
7
8
9
10
11
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;
}

3.退出功能

根据用户不同的选择,可以进行不同的功能,使用switch语句,当用户输入 0 时,可以实现退出通讯录的功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
while(true){
switch (select){
case 1: //添加联系人
break;
case 2: //显示联系人
break;
case 3: //删除联系人
break;
case 4: //查找联系人
break;
case 5: //修改联系人
break;
case 6://清空联系人
break;
case 0:
cout<<"欢迎下次使用"<<endl;
break;
default:
break;
}
}

4.功能实现

4.1添加联系人

封装addPerson函数

实现添加姓名,性别等属性时的操作基本一致,掌握其中一种便可以类推,关键是理解添加过程中的结构体指针使用过程,如 abk->person_array[abk->size].p_name还可以在每个添加的属性前面加一个while死循环判断,剔除非法值。注意注释的部分,能够更好的理解代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
void  add_Person(AddrBook *abk){
//判断是否超出容量
if(abk->size > MaxSize){
cout<<"当前通讯录已满,无法继续操作"<<endl;
return;
}

//添加姓名
string name; //存储输入的姓名,下面添加别的项同此作用
cout<<"请输入姓名: "<<endl;
cin>>name;
abk->person_array[abk->size].p_name=name;

//添加性别
int sex;
while(true){
//通过一个死循环,可以处理用户输入的非法数据,后面也可以进行类似操作使代码变得更加健壮
cout<<"请输入性别: "<<endl;
cout<<"1---男 2---女"<<endl;
cin>>sex;
if(sex == 1 || sex == 2){
abk->person_array[abk->size].p_sex=sex;
break;
}
cout <<"输入有误,请重新输入: "<<endl;

}
//添加年龄
int age;
cout<<"请输入年龄: "<<endl;
cin>>age;
abk->person_array[abk->size].p_age=age;

//添加电话
string phone;
cout<<"请输入联系电话: "<<endl;
cin>>phone;
abk->person_array[abk->size].p_phone=phone;

//添加地址
string address;
cout<<"请输入地址: "<<endl;
cin>>address;
abk->person_array[abk->size].p_address=address;

//添加成功后的操作
cout<<"添加成功"<<endl;
abk->size++;
system("pause");
system("cls");
}

在main函数中的操作为:

1
2
3
4
5
6
7
8
int main(){
//在main目录创建一个结构体对象并初始化
AddrBook abk;
abk.size=0;
...
case 1: //添加联系人
add_Person(&abk);
}

4.2显示联系人

设计思路:先判断通讯录为空和通讯录非空的情况,分别进行处理,当通讯录非空时,设计一个循环,根据传入的通讯录结构体指针所指明的size大小来设定循环次数,并且每次输出全部信息,每条信息通过”\t”(制表符,八个空格)隔开,注意输出性别信息时可以用if-else语句或者三目运算符来处理,保证输出“男”或“女”,最后进行清屏操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void showPerson(AddrBook *abk){
if(abk->size == 0){
cout <<"通讯录当前为空"<<endl;
}
else{
for(int i=0;i<abk->size;i++){
cout<<"姓名:"<<abk->person_array[i].p_name<<"\t"; //制表符相当于2个tab
cout<<"性别:"<<(abk->person_array[i].p_sex == 1 ? "男":"女") <<"\t"; //三目运算符的使用 可以不用if-else判断
cout<<"年龄:"<<abk->person_array[i].p_age<<"\t";
cout<<"电话:"<<abk->person_array[i].p_phone<<"\t";
cout<<"住址:"<<abk->person_array[i].p_address<<endl;
}
}
system("pause");
system("cls");
}

4.3 删除联系人

4.3.1 封装检测联系人函数

设计思路:第一个参数是通讯录,第二个参数是name,循环检测,如果找到了联系人返回联系人的数组下标,否则返回-1。

1
2
3
4
5
6
int isExit(AddrBook *abk,string name){
for(int i=0;i<abk->size;i++){
if(name == abk->person_array[i].p_name) return i;
}
return -1;
}

4.3.2 封装删除联系人函数

设计思路:通过 string name 存储用户输入的姓名,然后根据刚才封装的检测联系人函数处理函数结果为-1和不是-1的情况,当不为-1时,类似于顺序表的删除操作,将当前数组下标后面的元素全部前移一位,并且注意要最后将size --,并且进行清屏操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void deletePerson(AddrBook *abk){
string name;
cout<<"请输入要删除的联系人姓名"<<endl;
cin >> name;
//设置ret记录序号,注意从0开始的
int ret = isExit(abk,name);
if(ret == -1){
cout<<"联系人不存在"<<endl;
}else{
for(int i=ret;i < abk->size;i++){
abk->person_array[i]=abk->person_array[i+1];
}
abk->size--;
cout<<"联系人删除成功"<<endl;
};
}

4.4 查找联系人

设计思路:和上面类似,先用ret存储检测联系人函数的数组下标,然后利用位序输出信息即可,最后清屏操作~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void findPerson(AddrBook *abk){
cout<<"请输入要查找的联系人姓名:"<<endl;
string name;
cin >> name;
int ret = isExist(abk,name);
if(ret == -1){
cout <<"联系人不存在"<<endl;
}
else{
cout<<"查找成功"<<endl;
cout<<"姓名:"<<abk->person_array[ret].p_name <<"\t";
cout<<"性别:"<<(abk->person_array[ret].p_sex==1?"男":"女") <<"\t";
cout<<"年龄:"<<abk->person_array[ret].p_age <<"\t";
cout<<"电话:"<<abk->person_array[ret].p_phone <<"\t";
cout<<"住址:"<<abk->person_array[ret].p_address <<endl;
}
system("pause");
system("cls");
}

4.5修改联系人

设计思路:定义name记录用户输入的名称,然后调用isExist函数,并且用ret记录返回的值,然后根据ret来修改各个属性。修改性别时调用死循环来剔除非法输入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
void modifyPerson(AddrBook *abk){
cout<<"请输入要修改的联系人名称"<<endl;
string name;
cin >> name;
int ret = isExist(abk,name);
if(ret == -1){
cout <<"联系人不存在!"<<endl;
}else{
//修改姓名
cout <<"请输入姓名"<<endl;
string name1;
cin >> name1;
abk->person_array[ret].p_name=name;

//修改性别
cout<<"请输入性别"<<endl;
while(true){
cout<<"1--男 2--女"<<endl;
int sex;
cin >> sex;
if(sex == 1 || sex == 2){
abk->person_array[ret].p_sex=sex;
break;
}
else{
cout<<"输入有误,请重新输入"<<endl;
}
}

//修改年龄
cout <<"请输入年龄"<<endl;
int age;
cin >> age;
abk->person_array[ret].p_age=age;

//修改电话
cout <<"请输入电话"<<endl;
string phone;
cin >> phone;
abk->person_array[ret].p_phone=phone;

//修改住址
cout <<"请输入住址"<<endl;
string address;
cin >> address;
abk->person_array[ret].p_address=address;
cout <<"修改成功"<<endl;
}
system("pause");
system("cls");
}

4.6清空联系人

设计思路:直接指针调用通讯录,将size设为0即可~

1
2
3
4
5
6
void clearPerson(AddrBook *abk){
abk->size = 0;
cout<<"通讯录已清空"<<endl;
system("pause");
system("cls");
}

5.项目收获

熟悉了结构体嵌套(联系人结构体和通讯录结构体),结构体指针的调用(难点、关键点),学会使用了三目运算符,也有顺序表的基本操作穿插在其中,同时更加理解了项目背后的设计思路和测试流程。