今天的练习项目是建立通讯录管理系统。
其实也不能算是第一次接触c++项目,只是距离上一次正儿八经花时间写已经过去了很久很久。
建立一个c++项目主要可以分为以下几步:
- 创建新项目
- 确定实现功能
- 设计系统架构
- 书写代码
- 测试代码
- 优化代码
当然这也只是我自己这么总结的,肯定有不对或者不足的地方,都可再议。
【确定实现功能】
通讯录管理系统需要实现的功能涉及以下几个:
- 添加联系人
- 显示联系人
- 删除联系人
- 查找联系人
- 修改联系人
- 清空联系人
- 退出通讯录
此外,还需要一个菜单,也就是所有功能的显示界面。
【设计系统架构】
我理解为如何串联各个功能使之成为一个整体,或者说从总体上说各个功能是如何调用的。
首先,每个人应该是一个struct(Person),里面涉及的成员变量有:姓名(m_Name),性别(m_Sex),年龄(m_Age),联系电话(m_Phone),家庭住址(m_Address)。在这里,姓名和家庭住址是妥妥的string,年龄是int,而关于性别,考虑到用户输入时并不一定能够确保都能输成”男/女“,所以可以用int变量来表示,如果是1就表示男,2就表示女,而在输出时可以做一个转换;此外还有联系电话,可以用string来表示,理由是(这只是我觉得,并不一定正确)如果联系电话是int,很容易就出现超出INT_MAX的情况,如果使用string就不存在超出范围的问题。
其次,对于通讯录本身也应该是一个struct(Addressbook),里面涉及两个成员变量:Person型的数组,且数组大小有限制(通讯录不能无限扩大),通讯录的大小,用来判断通讯录是否超出限制范围,以及序号的增长。
- 菜单功能
菜单功能需要显示所有按键对应的功能,且每次操作结束后都能返回菜单。
- 退出通讯录
通讯录使用结束后需要退出系统,可以有提示语之类。
- 添加联系人
如果选择了添加联系人功能,那么系统就要提醒用户输入相应的内容,然后添加到通讯录对应的数组中,同时完成对通讯录大小的更新。(此处,我觉得可以有优化,可以增加如果出现重复添加可以提醒用户)
- 显示联系人
显示通讯录中所有信息,尽量是一行表示一个人的相关信息。
- 删除联系人
判断该联系人是否存在于通讯录中,如果存在,则进行删除操作,这里使用的是将后续的信息往前覆盖的方法,同时注意修改通讯录的大小;如果不存在,则提醒用户该联系人不存在。
- 查找联系人
判断该联系人是否存在于通讯录中,如果存在,则进行输出操作(此处,我觉得可以把输出信息封装成一个函数,因为在整个系统里好像多次使用到了输出整行信息的功能);如果不存在,则提醒用户该联系人不存在。
- 修改联系人
判断该联系人是否存在于通讯录中,如果存在,则进行修改;如果不存在,则提醒用户该联系人不存在。(此处,我觉得可以把操作改成添加新的信息)
- 清空联系人
直接将通讯录的大小置0,实现逻辑上的清空。(此处,我认为可以优化的地方有两点,一是能否实现逻辑和物理上的双重清空,二是在实现清空的时候对用户进行二次确认,以防出现误删的操作)。
整体架构大概如此,教程中使用了数组来存储信息,但我觉得用map会更好一点?
先放上按教程写的代码
#include#include #define MAX 1000 using namespace std; //设计联系人结构体 struct Person { string m_Name;//姓名 int m_Sex;//性别,1:男,2:女 int m_Age;//年纪 string m_Phone;//电话 string m_Address;//地址 }; //设计通讯录结构体 struct Addressbook { struct Person addressArray[MAX]; int m_Size; }; //显示菜单 void showMenu() { cout << "1、添加联系人" << endl; cout << "2、显示联系人" << endl; cout << "3、删除联系人" << endl; cout << "4、查找联系人" << endl; cout << "5、修改联系人" << endl; cout << "6、清空联系人" << endl; cout << "0、退出通讯录" << endl; } //添加联系人 void addPerson(Addressbook* abs) { if (abs->m_Size == MAX) { cout << "通讯录已满,无法添加!" << endl; return; } else { string name; int sex = 0; int age = 0; string phone; string address; cout << "请输入姓名" << endl; cin >> name; abs->addressArray[abs->m_Size].m_Name = name; cout << "请输入性别" << endl; cout << "1---男" << endl; cout << "2---女" << endl; while (true) { cin >> sex; if (sex == 1 || sex == 2) { abs->addressArray[abs->m_Size].m_Sex = sex; break; } cout << "输入错误,请重新输入!" << endl; } cout << "请输入年龄" << endl; while (true) { cin >> age; if (age > 0 && age <= 100) { abs->addressArray[abs->m_Size].m_Age = age; break; } cout << "输入有误,请重新输入!" << endl; } cout << "请输入联系电话" << endl; cin >> phone; abs->addressArray[abs->m_Size].m_Phone = phone; cout << "请输入家庭住址" << endl; cin >> address; abs->addressArray[abs->m_Size].m_Address = address; abs->m_Size++; cout << "添加成功!" << endl; } system("pause");//按任意键 system("cls");//清屏 } //显示联系人 void showPerson(Addressbook* abs) { if (abs->m_Size == 0) { cout << "当前记录为空" << endl; } else { for (int i = 0; i < abs->m_Size; i++) { cout << "姓名:" << abs->addressArray[i].m_Name << "t"; cout << "性别:" << (abs->addressArray[i].m_Sex == 1? "男" : "女") << "t"; cout << "年龄:" << abs->addressArray[i].m_Age << "t"; cout << "联系电话:" << abs->addressArray[i].m_Phone << "t"; cout << "家庭住址:" << abs->addressArray[i].m_Address << endl; } } system("pause"); system("cls"); } //删除联系人 //判断该联系人是否存在 int isExist(Addressbook* abs, string name) { for (int i = 0; i < abs->m_Size; i++) { if (abs->addressArray[i].m_Name == name) { return i; } } return -1; } void deletePerson(Addressbook* abs) { cout << "请输入删除联系人姓名" << endl; string name; cin >> name; int ret = isExist(abs, name); if (ret == -1) { cout << "查无此人" << endl; } else { for (int i = ret; i < abs->m_Size; i++) { abs->addressArray[i] = abs->addressArray[i + 1]; } abs->m_Size--; cout << "删除成功!" << endl; } system("pause"); system("cls"); } //查找联系人 void findPerson(Addressbook* abs) { cout << "请输入查找联系人姓名" << endl; string name; cin >> name; int ret = isExist(abs, name); if (ret == -1) { cout << "查无此人" << endl; } else { cout << "姓名:" << abs->addressArray[ret].m_Name << "t"; cout << "性别:" << (abs->addressArray[ret].m_Sex == 1 ? "男" : "女") << "t"; cout << "年龄:" << abs->addressArray[ret].m_Age << "t"; cout << "联系电话:" << abs->addressArray[ret].m_Phone << "t"; cout << "家庭住址:" << abs->addressArray[ret].m_Address << endl; } system("pause"); system("cls"); } //修改联系人 void modifyPerson(Addressbook* abs) { cout << "请输入修改联系人姓名" << endl; string name; cin >> name; int ret = isExist(abs, name); if (ret == -1) { cout << "查无此人" << endl; } else { cout << "找到此人" << endl; string name; cout << "请输入姓名" << endl; cin >> name; abs->addressArray[ret].m_Name = name; int sex = 0; cout << "请输入性别" << endl; cout << "1---男" << endl; cout << "2---女" << endl; while (true) { cin >> sex; if (sex == 1 || sex == 2) { abs->addressArray[ret].m_Sex = sex; break; } cout << "输入有误,请重新输入!" << endl; } int age = 0; cout << "请输入年龄" << endl; cin >> age; abs->addressArray[ret].m_Age = age; string phone; cout << "请输入联系电话" << endl; cin >> phone; abs->addressArray[ret].m_Phone = phone; string address; cout << "请输入家庭住址" << endl; cin >> address; abs->addressArray[ret].m_Address = address; cout << "修改成功!" << endl; } system("pause"); system("cls"); } //清空联系人 void cleanPerson(Addressbook* abs) { abs->m_Size = 0;//将当前通讯录的大小置为0就可以达到逻辑上的清空 cout << "通讯录已清空!" << endl; system("pause"); system("cls"); } int main() { Addressbook abs;//创建通讯录 abs.m_Size = 0; int select = 0;//用户选择 //用死循环来保证只要不是选择退出系统就可以一直在操作完成之后返回菜单界面,然后重新进行选择 //选择使用switch来实现按键功能 while (true) { showMenu(); cin >> select; switch (select) { case 1 : addPerson(&abs);//用引用是为了可以直接在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 0 : cout << "欢迎下次使用" << endl; system("pause"); return 0; break; default: break; } } system("pause"); return 0; }
再放上我自己优化的:存放信息的容器改成了unordered_map,添加联系人时如果已存在就提醒用户,修改联系人时如果不存在直接改成添加联系人,封装了输出函数,实现了物理和逻辑上的清空。
#include#include #include #define MAX 1000 using namespace std; //设计联系人结构体 struct Person { string m_Name;//姓名 int m_Sex;//性别,1:男,2:女 int m_Age;//年纪 string m_Phone;//电话 string m_Address;//地址 }; //设计通讯录结构体 struct Addressbook { unordered_map mp; }; //显示信息 void showInfo(Addressbook* abs, string name) { cout << "姓名:" << abs->mp[name].m_Name << "t"; cout << "性别:" << (abs->mp[name].m_Sex == 1 ? "男" : "女") << "t"; cout << "年龄:" << abs->mp[name].m_Age << "t"; cout << "联系电话:" << abs->mp[name].m_Phone << "t"; cout << "家庭住址:" << abs->mp[name].m_Address << endl; } //显示菜单 void showMenu() { cout << "1、添加联系人" << endl; cout << "2、显示联系人" << endl; cout << "3、删除联系人" << endl; cout << "4、查找联系人" << endl; cout << "5、修改联系人" << endl; cout << "6、清空联系人" << endl; cout << "0、退出通讯录" << endl; } //添加联系人 void addPerson(Addressbook* abs) { if (abs->mp.size() == MAX) { cout << "通讯录已满,无法添加!" << endl; return; } else { string name; int sex = 0; int age = 0; string phone; string address; cout << "请输入姓名" << endl; cin >> name; if (abs->mp.find(name) == abs->mp.end()) { abs->mp[name].m_Name = name; cout << "请输入性别" << endl; cout << "1---男" << endl; cout << "2---女" << endl; while (true) { cin >> sex; if (sex == 1 || sex == 2) { abs->mp[name].m_Sex = sex; break; } cout << "输入错误,请重新输入!" << endl; } cout << "请输入年龄" << endl; while (true) { cin >> age; if (age > 0 && age <= 100) { abs->mp[name].m_Age = age; break; } cout << "输入有误,请重新输入!" << endl; } cout << "请输入联系电话" << endl; cin >> phone; abs->mp[name].m_Phone = phone; cout << "请输入家庭住址" << endl; cin >> address; abs->mp[name].m_Address = address; cout << "添加成功!" << endl; } else { cout << "该联系人已存在!" << endl; } } system("pause");//按任意键 system("cls");//清屏 } //显示联系人 void showPerson(Addressbook* abs) { if (abs->mp.size() == 0) { cout << "当前记录为空" << endl; } else { for (auto& ch : abs->mp) { showInfo(abs, ch.first); } } system("pause"); system("cls"); } //删除联系人 //判断该联系人是否存在 void deletePerson(Addressbook* abs) { cout << "请输入删除联系人姓名" << endl; string name; cin >> name; if (abs->mp.find(name) == abs->mp.end()) { cout << "查无此人" << endl; } else { abs->mp.erase(name); cout << "删除成功!" << endl; } system("pause"); system("cls"); } //查找联系人 void findPerson(Addressbook* abs) { cout << "请输入查找联系人姓名" << endl; string name; cin >> name; if (abs->mp.find(name) == abs->mp.end()) { cout << "查无此人" << endl; } else { showInfo(abs, name); } system("pause"); system("cls"); } //修改联系人 void modifyPerson(Addressbook* abs) { cout << "请输入修改联系人姓名" << endl; string name; cin >> name; if (abs->mp.find(name) == abs->mp.end()) { addPerson(abs); cout << "修改成功!" << endl; } else { cout << "找到此人" << endl; int sex = 0; cout << "请输入性别" << endl; cout << "1---男" << endl; cout << "2---女" << endl; while (true) { cin >> sex; if (sex == 1 || sex == 2) { abs->mp[name].m_Sex = sex; break; } cout << "输入有误,请重新输入!" << endl; } int age = 0; cout << "请输入年龄" << endl; cin >> age; abs->mp[name].m_Age = age; string phone; cout << "请输入联系电话" << endl; cin >> phone; abs->mp[name].m_Phone = phone; string address; cout << "请输入家庭住址" << endl; cin >> address; abs->mp[name].m_Address = address; cout << "修改成功!" << endl; } system("pause"); system("cls"); } //清空联系人 void cleanPerson(Addressbook* abs) { cout << "请输入1确认清空通讯录" << endl; int ret = 0; cin >> ret; if (ret == 1) { abs->mp.clear(); cout << "通讯录已清空!" << endl; } system("pause"); system("cls"); } int main() { Addressbook abs;//创建通讯录 abs.mp.clear(); int select = 0;//用户选择 //用死循环来保证只要不是选择退出系统就可以一直在操作完成之后返回菜单界面,然后重新进行选择 //选择使用switch来实现按键功能 while (true) { showMenu(); cin >> select; switch (select) { case 1: addPerson(&abs);//用引用是为了可以直接在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 0: cout << "欢迎下次使用" << endl; system("pause"); return 0; break; default: break; } } system("pause"); return 0; }



