当前位置: 首页 > news >正文

通讯录扩展(计科实验一改进)

模仿手机中通讯录管理,根据分析,选择合适的数据结构,先实现通讯录条目管理程序,然后实现通讯录管理。

一、头文件设置(contact.h)

设置三个结构体,分别对应于一般联系人、亲朋好友联系人和通讯录。同时,设置六个函数(后续可以改为类操作等),用来实现displayMenu()函数中的六大功能。

为方便操作和适应模块化处理,将结构体、头文件等集中到contact.h头文件中。

#头文件引用名称为 contact.h #include <iostream> #include <string> #include <fstream> #include <sstream> using namespace std; // 一般联系人结构体 struct CommEntry { string name; // 姓名 string tel; // 电话 string adrress; // 地址 }; // 亲朋好友联系人结构体 struct CommEntryFriend { string name; // 姓名 string tel; // 电话 string email; // 邮箱 string address; // 地址 }; // 通讯录类,包含添加、删除、修改、查询等功能 struct Comms { void InputCommEntry(CommEntry*& ce, CommEntryFriend*& fd); void OutputCommEntry(const CommEntry ce[], const CommEntryFriend fd[]); void Delete(CommEntry*& ce, CommEntryFriend*& fd, string delete_name); void Modify(CommEntry*& ce, CommEntryFriend*& fd, string old_name); int ReadFile(CommEntry*& ce, CommEntryFriend*& fd); void SaveFile(CommEntry*& ce, CommEntryFriend*& fd); };

二、 头文件引用,以及全局变量的定义

#include "contact.h" int a = 0; int f = 0; int capacity = 2; // 一般联系人初始容量,随添加联系人自动扩展 int capacity_f = 2; // 亲朋好友联系人初始容量,随添加联系人自动扩展

三、添加联系人模块

支持对联系人进行分类,分为亲朋好友和一般联系人,两者所包含的信息也有所不同。

// 输入联系人信息(根据选择是一般联系人还是亲朋好友) void InputCommEntry(CommEntry*& ce, CommEntryFriend*& fd) { cout << "------------------------------" << endl; cout << "请选择新添加的联系人是哪种类型" << endl; cout << "1.一般联系人" << endl; cout << "2.亲朋 好友" << endl; cout << "------------------------------" << endl; cout << "请选择1或2: "; int check; // 接收用户的选择 cin >> check; if (check != 1 && check != 2) { cout << "添加失败" << endl; return; } switch (check) { case 1: { // 添加一般联系人 if (a >= capacity) { capacity *= 2; // 容量扩大一倍 CommEntry* temp = new CommEntry[capacity]; // 创建新的数组 for (int i = 0; i < a; i++) { temp[i] = ce[i]; // 复制原数据到新数组 } delete[] ce; // 释放原数组内存 ce = temp; // 指向新的内存 } cout << "Name: "; cin >> ce[a].name; cout << "Tel : "; cin >> ce[a].tel; cout << "Address: "; cin >> ce[a].adrress; a++; // 增加联系人数量 cout << "添加成功" << endl; break; } case 2: { if (f >= capacity_f) { capacity_f *= 2; // 容量扩大一倍 CommEntryFriend* temp_f = new CommEntryFriend[capacity_f]; //创建新的数组 for (int i = 0; i < f; i++) { temp_f[i] = fd[i]; // 复制原数据到新数组 } delete[] fd; // 释放原数组内存 fd = temp_f; // 指向新的内存 } cout << "Name: "; cin >> fd[f].name; cout << "Tel : "; cin >> fd[f].tel; cout << "Email: "; cin >> fd[f].email; cout << "Address: "; cin >> fd[f].address; f++; // 增加联系人数量 cout << "添加成功" << endl; break; } } }

四、输出通讯录

可以选择输出一般联系人 or 亲朋好友,也包含了对通讯录为空情况的检查。

// 输出联系人信息(支持显示不同类型的联系人) void OutputCommEntry(const CommEntry ce[], const CommEntryFriend fd[]) { if (a == 0) { cout << "通讯录为空" << endl; return; } cout << "------------------------------" << endl; cout << "请选择展示的联系人是哪种类型" << endl; cout << "1.一般联系人" << endl; cout << "2.亲朋 好友" << endl; cout << "3.全部联系人" << endl; cout << "------------------------------" << endl; cout << "请选择1或2或3: "; int check; // 接收用户的选择 cin >> check; switch (check) { case 1: if (a == 0) { cout << "一般联系人通讯录为空,请先添加" << endl; break; } for (int i = 0; i < a; i++) { cout << "Name: " << ce[i].name << endl; cout << "Tel : " << ce[i].tel << endl; cout << "Address: " << ce[i].adrress << endl; cout << "\n"; } break; case 2: if (f == 0) { cout << "亲朋好友联系人通讯录为空,请先添加" << endl; break; } for (int i = 0; i < f; i++) { cout << "Name: " << fd[i].name << endl; cout << "Tel : " << fd[i].tel << endl; cout << "Tel : " << fd[i].email << endl; cout << "Address: " << fd[i].address << endl; cout << "\n"; } break; case 3: for (int i = 0; i < a; i++) { cout << "Name: " << ce[i].name << endl; cout << "Tel : " << ce[i].tel << endl; cout << "Address: " << ce[i].adrress << endl; cout << "\n"; } for (int i = 0; i < f; i++) { cout << "Name: " << fd[i].name << endl; cout << "Tel : " << fd[i].tel << endl; cout << "Tel : " << fd[i].email << endl; cout << "Address: " << fd[i].address << endl; cout << "\n"; } break; default: cout << "输出失败" << endl; break; } }

五、删除某一联系人

通过先后遍历亲朋好友和一般联系人数组,定位到第一个被查找到的人,然后对其进行覆盖删除,实现粗略的删除

void Delete(CommEntry*& ce, CommEntryFriend*& fd, string delete_name) { int b = a; for (int i = 0; i < a; i++) { // 删除一般联系人 if (ce[i].name == delete_name) { // 删除的是最后一个联系人 if (i == a - 1) { ce[i].adrress = ""; ce[i].name = ""; ce[i].tel = ""; a--; break; } // 删除联系人并缩小数组 for (int j = i; j < a - 1; j++) { ce[j] = ce[j + 1]; a--; break; } break; } } // 如果没有删除一般联系人,尝试删除亲朋好友联系人 if (b == a) { b = f; for (int i = 0; i < f; i++) { // 删除的是最后一个联系人 if (i == f - 1) { fd[i].address = ""; fd[i].email = ""; fd[i].name = ""; fd[i].tel = ""; f--; break; } // 删除联系人并缩小数组 if (fd[i].name == delete_name) { for (int j = i; j < b - 1; j++) { fd[j] = fd[j + 1]; f--; break; } break; } } if (b == f) cout << "没有该联系人!" << endl; else cout << "删除成功" << endl; } else cout << "删除成功" << endl; }

六、修改联系人信息

通过联系人姓名来确定联系人第一次出现的位置,然后根据此人的所处的类型,提供修改指定信息的选择,但是只支持修改一次。

void Modify(CommEntry*& ce, CommEntryFriend*& fd, string old_name) { int check = 0; // 判断是否有此人 0:没有 1:有 2:不修改了 for (int i = 0; i < a; i++) { // 提供修改选项 if (ce[i].name == old_name) { cout << "----------------" << endl; cout << " 1.修改姓名 " << endl; cout << " 2.修改电话 " << endl; cout << " 3.修改地址 " << endl; cout << " 4. 退出 " << endl; cout << "----------------" << endl; cout << "请选择1或2或3或4 : "; int choice; //记录选择 cin >> choice; switch (choice) { case 1: { cout << "请输入新姓名: "; string new_name; cin >> new_name; ce[i].name = new_name; cout << "修改成功" << endl; break; } case 2: { cout << "请输入新电话: "; string new_tel; cin >> new_tel; ce[i].tel = new_tel; cout << "修改成功" << endl; break; } case 3: { cout << "请输入新地址: "; string new_ad; cin >> new_ad; ce[i].adrress = new_ad; cout << "修改成功" << endl; break; } case 4: break; default: { cout << "选择无效" << endl; choice = 4; break; } } if (choice == 4) return; else check = 1; break; } } if (check == 0) { // 查找亲朋好友联系人 for (int i = 0; i < f; i++) { if (fd[i].name == old_name) { cout << "----------------" << endl; cout << " 1.修改姓名 " << endl; cout << " 2.修改电话 " << endl; cout << " 3.修改邮箱 " << endl; cout << " 4.修改地址 " << endl; cout << " 5. 退出 " << endl; cout << "----------------" << endl; cout << "请选择1或2或3 : "; int choice; //记录选择 cin >> choice; switch (choice) { case 1: { cout << "请输入新姓名: "; string new_name; cin >> new_name; fd[i].name = new_name; cout << "修改成功" << endl; break; } case 2: { cout << "请输入新电话: "; string new_tel; cin >> new_tel; fd[i].tel = new_tel; cout << "修改成功" << endl; break; } case 3: { cout << "请输入新邮箱: "; string new_email; cin >> new_email; fd[i].email = new_email; cout << "修改成功" << endl; break; } case 4: { cout << "请输入新地址: "; string new_ad; cin >> new_ad; fd[i].address = new_ad; cout << "修改成功" << endl; break; } case 5: { return; } default: { cout << "选择无效" << endl; return; } } check = 1; break; } } } if (check == 0) { cout << "查无此人" << endl; } }

七、查找指定联系人

此项功能提供了精确查找和模糊查找,精确查找通过姓名和手机号双重确定联系人,模糊查找只通过姓名进行查找,为了确保查找信息的清晰明确,只展示首个被查找到的用户。因此,这就需要用户在添加联系人时,避免重复添加姓名或手机号相同的联系人信息。

void Search(CommEntry*& ce, CommEntryFriend*& fd) { cout << "------------" << endl; cout << " 1.精确查找 " << endl; cout << " 2.模糊查找 " << endl; cout << " 3. 退出 " << endl; cout << "------------" << endl; cout << "请选择1或2或3: "; int check; // 接收用户的选择 cin >> check; switch (check) { case 1: { cout << "请输入要查找的姓名: "; string s_name; cin >> s_name; cout << "请输入手机号: "; string s_tel; cin >> s_tel; for (int i = 0; i < a; i++) { if (ce[i].name == s_name) { if (ce[i].tel == s_tel) { cout << "查找成功" << endl; cout << "姓名: " << ce[i].name << endl; cout << "电话: " << ce[i].tel << endl; cout << "地址: " << ce[i].adrress << endl; return; } } } for (int i = 0; i < f; i++) { if (fd[i].name == s_name) { if (ce[i].tel == s_tel) { cout << "查找成功" << endl; cout << "姓名: " << fd[i].name << endl; cout << "电话: " << fd[i].tel << endl; cout << "地址: " << fd[i].email << endl; cout << "地址: " << fd[i].address << endl; return; } } } cout << "没有该人" << endl; return; } case 2: { cout << "请输入要查找的姓名: "; string s_name; cin >> s_name; for (int i = 0; i < a; i++) { if (ce[i].name == s_name) { cout << "查找成功" << endl; cout << "姓名: " << ce[i].name << endl; cout << "电话: " << ce[i].tel << endl; cout << "地址: " << ce[i].adrress << endl; return; } } for (int i = 0; i < f; i++) { if (fd[i].name == s_name) { cout << "查找成功" << endl; cout << "姓名: " << fd[i].name << endl; cout << "电话: " << fd[i].tel << endl; cout << "地址: " << fd[i].email << endl; cout << "地址: " << fd[i].address << endl; return; } } cout << "没有该人" << endl; return; } case 3: { return; } default:{ cout << "输入无效" << endl; return; } } }

八、菜单栏展示

在控制台上向用户展示可以实现的功能。

int displayMenu() { int choice; cout << "\n|-----------------|" << endl; cout << "|1. 添 加 联 系 人|" << endl; cout << "|2. 删 除 联 系 人|" << endl; cout << "|3. 修改联系人信息|" << endl; cout << "|4. 查 询 联 系 人|" << endl; cout << "|5. 展 示 联 系 人|" << endl; cout << "|6. 退 出 |" << endl; cout << "|-----------------|" << endl; cout << "请选择(0-5):"; cin >> choice; return choice; }

九、文件的读取和存储

使用文本文件(.txt)存储数据,确保程序退出后数据不丢失。并通过文件流操作,实现数据的导入和导出功能。

int ReadFile(CommEntry*& ce, CommEntryFriend*& fd) { // 打开文件,注意ios::in是读取模式 std::ifstream FILE("Information.txt", std::ios::in); // 检查文件是否成功打开 if (!FILE) { std::cerr << "文件无法打开!" << std::endl; return 1; } int check = 0; std::string line; std::getline(FILE, line); std::string temp; std::stringstream ss(line); std::getline(ss, temp, ','); if (temp == "一般联系人") { while (std::getline(FILE, line)) { if (a >= capacity) { capacity *= 2; // 容量扩大一倍 CommEntry* temp = new CommEntry[capacity]; // 创建新的数组 for (int i = 0; i < a; i++) { temp[i] = ce[i]; } delete[] ce; ce = temp; } std::string temp; std::stringstream ss(line); std::getline(ss, temp, ','); if (temp == "亲朋好友") { check = 1; break; } ce[a].name = temp; // 读取姓名 std::getline(ss, temp, ','); ce[a].tel = temp; // 读取电话号码 std::getline(ss, temp, ','); ce[a].adrress = temp; // 读取地址 a++; } if (check == 1) { while (std::getline(FILE, line)) { if (f >= capacity_f) { capacity_f *= 2; // 容量扩大一倍 CommEntryFriend* temp_f = new CommEntryFriend[capacity_f]; // 创建新的数组 for (int i = 0; i < f; i++) { temp_f[i] = fd[i]; } delete[] fd; fd = temp_f; } std::string temp; std::stringstream ss(line); std::getline(ss, temp, ','); fd[f].name = temp; // 读取姓名 std::getline(ss, temp, ','); fd[f].tel = temp; // 读取电话号码 std::getline(ss, temp, ','); fd[f].email = temp; // 读取邮箱 std::getline(ss, temp, ','); fd[f].address = temp; // 读取地址 f++; } } return 0; } else { if (temp == "亲朋好友") { while (std::getline(FILE, line)) { if (f >= capacity_f) { capacity_f *= 2; // 容量扩大一倍 CommEntryFriend* temp_f = new CommEntryFriend[capacity_f]; // 创建新的数组 for (int i = 0; i < f; i++) { temp_f[i] = fd[i]; } delete[] fd; fd = temp_f; } std::string temp; std::stringstream ss(line); std::getline(ss, temp, ','); fd[f].name = temp; // 读取姓名 std::getline(ss, temp, ','); fd[f].tel = temp; // 读取电话号码 std::getline(ss, temp, ','); fd[f].email = temp; // 读取邮箱 std::getline(ss, temp, ','); fd[f].address = temp; // 读取地址 f++; } } return 0; } return 0; } void SaveFile(CommEntry*& ce, CommEntryFriend*& fd) { std::ofstream FILE("Information.txt", std::ios::out); // 打开文件 // 保存一般联系人 FILE << "一般联系人,格式: 姓名,电话,地址" << endl; for (int i = 0; i < a; i++) { FILE << ce[i].name << "," << ce[i].tel << "," << ce[i].adrress << endl; } // 保存亲朋好友联系人 FILE << "亲朋好友,格式: 姓名,电话,邮箱,地址" << endl; for (int i = 0; i < f; i++) { FILE << fd[i].name << "," << fd[i].tel << "," << fd[i].email << "," << fd[i].address << endl; } }

十、主函数设置

int main() { CommEntry* ce = new CommEntry[capacity]; // 动态分配初始容量,一般联系人数组 CommEntryFriend* fd = new CommEntryFriend[capacity_f]; // 亲朋好友联系人数组 if (ReadFile(ce, fd)) // 读取文件联系人信息 return 0; int iChoice = 1; int check = 0; while (iChoice != 0) { iChoice = displayMenu(); switch (iChoice) { case 1: InputCommEntry(ce,fd); // 添加联系人 break; case 2: { cout << "请输入你要删除的姓名: "; string delete_name; cin >> delete_name; Delete(ce, fd, delete_name); // 删除联系人 break; } case 3: { string old_name; cout << "请输入你要修改的联系人的姓名: "; cin >> old_name; Modify(ce, fd, old_name); // 修改联系人 break; } case 4: { Search(ce, fd); // 查找联系人 break; } case 5: OutputCommEntry(ce, fd); // 输出联系人 break; case 6: { SaveFile(ce, fd); // 保存联系人信息 iChoice = 0; break; } default: cout << "无效选择,请重新输入." << endl; } } }

十一、测试数据(Information.txt)

一般联系人,格式: 姓名,电话,地址 1,1,1 2,2,2 3,3,3 亲朋好友,格式: 姓名,电话,邮箱,地址 5,5,5,5 6,6,6,6

这是对上一简单的通讯录的改进,还有诸多功能有待改进和开发,希望能对大家有所帮助,代码运行若出现瑕疵,还请大家多多包涵,如果对本文章中的代码有不清楚的地方,欢迎大家随时来联系我。

须知少日拏云志,曾许人间第一流。我们还年轻,我们还有无限可能!

http://www.gsyq.cn/news/1416579.html

相关文章:

  • QiLink 社区核心共建者证书
  • 终极Zotero SciHub插件:3步实现学术文献PDF自动下载
  • AI服务变现瓶颈突破,深度拆解Gemini客单价卡点与12个精准提价触点
  • 用Unity Tilemap复刻《超级马里奥》第一关:手把手教你搭建童年经典游戏场景
  • Hy-MT1.5-1.8B-2bit模型架构详解:从HunYuanDenseV1到SEQ量化
  • 一文读懂EASI基准测试:SenseNova-SI-1.5-InternVL3-8B如何碾压开源竞品?
  • 昇腾NPU上YOLOv5模型定制完全指南:从自定义数据集到模型优化的实战教程
  • SLANeXt_wireless_onnx技术原理详解:深度学习在表格识别中的创新应用
  • 终极音乐解锁教程:3分钟学会免费解密QQ音乐、网易云加密文件
  • 【Sora 2数字人商业落地白皮书】:覆盖电商/教育/金融三大场景的12类合规性风险清单(含广电总局最新备案要点)
  • vim-plug终极指南:3分钟学会Vim插件管理,打造高效开发环境
  • 3步掌握三星固件下载:Bifrost跨平台工具完整指南
  • Redis 缓存雪崩把我搞了一周,我叛逃到 DragonflyDB 的血泪史(附避坑指南)
  • 猫抓Cat-Catch:终极网页媒体嗅探工具,3步搞定视频音频下载
  • 基于BNO055与Arduino的手势控制像素赛车游戏开发全解析
  • 【系统学AI】08 Plan-then-Execute范式:先想好再做,比ReAct强在哪
  • 3分钟学会网页视频下载:猫抓资源嗅探工具终极指南
  • 3PEAK思瑞浦 TPA6062-VS1R MSOP8 运算放大器
  • 避开版本坑!用Conda虚拟环境+清华源5分钟搞定Transformer安装(附测试代码)
  • 【仅剩237份】DeepSeek多租户安全基线检查清单(含21项CVE关联项、13个租户越权高危场景)
  • 2026徐州黄金回收避坑指南于门店推荐:选聚奢名品,不扣点不熔金,支持上门回收 - 寻茫精选
  • Deep-Live-Cam终极指南:5分钟实现实时人脸替换与一键深度伪造
  • Sora 2数字人唇音同步误差<0.12帧:基于Wav2Lip++改进算法的实时声画对齐实战(附GitHub可运行代码库)
  • Suncast模型性能揭秘:如何实现MAE 76.19 W/m²的高精度太阳能预测
  • 如何永久保存微信聊天记录?完全免费的本地数据备份终极指南
  • 如何在Blender中快速创建VRM角色:5分钟掌握VRM插件的完整指南
  • 通过taotoken cli在ubuntu上快速为openclaw写入配置
  • Honey Select 2终极汉化与模组整合方案:3步解决语言障碍与功能限制
  • Pythoncollections模块深究
  • Arduino机器人平台:模式切换架构与多传感器集成实践