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