当前位置: 首页 > 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.jsqmd.com/news/905283/

相关文章:

  • 从‘看不懂’到‘门儿清’:手把手教你读懂Linux性能监控命令的输出(附真实案例)
  • QiLink 社区核心共建者证书
  • Arduino自动驾驶模拟电路:从传感器协同到系统集成的嵌入式实践
  • 【全平台通杀!】小白必看:Win/Mac/Linux 都能用的 OpenClaw 安装指南(包含安装包)
  • 【AI 时代软件工程师的算法图谱】05 二分查找:在不确定性中定位边界
  • 终极Zotero SciHub插件:3步实现学术文献PDF自动下载
  • 基于nRF52832的无零线BLE智能开关改造方案详解
  • job-listing-relevance-model终极指南:从模型下载到生产部署全流程
  • 终极指南:如何用Universal x86 Tuning Utility一键解锁Intel/AMD硬件隐藏性能
  • Unlock-Music终极指南:免费解锁10+音乐平台加密格式的完整教程
  • 用Unity Tilemap复刻《超级马里奥》第一关:手把手教你搭建童年经典游戏场景
  • AI服务变现瓶颈突破,深度拆解Gemini客单价卡点与12个精准提价触点
  • 认识电子元器件 —— 存储器篇:参数、选型与应用
  • Hy-MT1.5-1.8B-2bit模型架构详解:从HunYuanDenseV1到SEQ量化
  • Nginx配置文件泄露实战:利用Python编码特性绕过URL过滤(附POC脚本)
  • Claude Code用户如何配置Taotoken以解决访问不稳定问题
  • 一文读懂EASI基准测试:SenseNova-SI-1.5-InternVL3-8B如何碾压开源竞品?
  • SpaceX 自研 AI 训练栈:适配 22 万 GPU 集群,大规模训练比 JAX 提速一个数量级以上
  • SLANeXt_wireless_onnx技术原理详解:深度学习在表格识别中的创新应用
  • 昇腾NPU上YOLOv5模型定制完全指南:从自定义数据集到模型优化的实战教程
  • 终极VSCode摸鱼神器:Qwerty Learner让程序员边写代码边背单词的完整指南
  • Qwen3.5-397B-A17B完整指南:如何在华为昇腾NPU上部署3970亿参数大模型
  • 终极音乐解锁教程:3分钟学会免费解密QQ音乐、网易云加密文件
  • 从根目录到Super分区:手把手带你认识安卓手机的系统‘地盘’(附精简系统实战)
  • Arduino与L298N驱动直流电机:PWM调速与H桥控制全解析
  • vim-plug终极指南:3分钟学会Vim插件管理,打造高效开发环境
  • Smithbox深度解析:5大核心模块实现原理与系统级游戏修改架构
  • 【Sora 2数字人商业落地白皮书】:覆盖电商/教育/金融三大场景的12类合规性风险清单(含广电总局最新备案要点)
  • OpCore-Simplify:3步自动化配置黑苹果OpenCore EFI的终极方案
  • 3步掌握三星固件下载:Bifrost跨平台工具完整指南