c++vscode多文件实现通讯录管理系统

ops/2024/9/24 12:24:04/

vscode_0">c++vscode多文件实现通讯录管理系统

作为c++入门级别的实战项目,此通讯管理系统项目不仅仅是对c++入门阶段学习成果的检验,也是对c++基础知识的回顾,体会c++在实战制作中的思路,是入门c++单文件实现通讯录系统的改进

img

在这里插入图片描述

一、多文件通讯录管理系统简介

系统需求通讯录是一个可以记录亲人、好友信息的工具。

本教程主要利用C++来实现一个通讯录管理系统系统中需要实现的功能如下:

  • 添加联系人:向通讯录中添加新人,信息包括(姓名、性别、年龄、联系电话、家庭住址)最多记录1000人
  • 显示联系人:显示通讯录中所有联系人信息
  • 删除联系人:按照姓名进行删除指定联系人
  • 查找联系人:按照姓名查看指定联系人信息
  • 修改联系人:按照姓名重新修改指定联系人
  • 清空联系人:清空通讯录中所有信息
  • 退出通讯录:退出当前使用的通讯录

相对于原先通讯录管理系统优化之处:

  1. 添加读取文件保存进独立文件功能,记录,使下次运行时保存原先的联系人
  2. 多文件协同运行,包括头文件.h和文件.cpp
  3. 可以批量添加多人

二、思路

image-20240830211437479

三、功能实现

3.1 person.h封装

image-20240830211756354

#pragma once // 防止文件重复
#include <iostream>
#include <string>
using namespace std;
class Person
{
public:string Name;    // 联系人姓名int Age;        // 联系人年龄int Sex;        // 联系人性别,后续1表示男,2表示女string Address; // 联系人地址string Phone;   // 联系人电话Person();// 初始化人Person(string name, int age, int sex, string phone, string address);
};

person.cpp实现如下:

#include "person.h"
Person::Person()
{
}
Person::Person(string name, int age, int sex, string phone, string address)
{Name = name;Age = age;Sex = sex;Phone = phone;Address = address;
}

3.2 manager.h类封装

image-20240830212420597

#pragma once // 防止文件重复
#include <iostream>
#include <string>
using namespace std;
#include "person.h"
#define MAX 1000//便于后期维护
#define FILE_NAME "person.txt"//便于后期维护
class Manager
{
public:Person arr[MAX]; // 创建一个z最大能容纳1000个人的数组int num;         // 记录当前有多少人// 构造函数,判断文件状态Manager();// 得到原先文件联系人数量int getNum();// 初始化程序void init();// 读取保存文件void save();// 显示菜单void showMenu();// 退出功能void Exit();// 添加联系人功能void addPerson();// 创建判断文件是否为空的标志,以便查看联系人功能实现bool isEmpty = false;// 添加查看联系人功能void showPerson();// 删除联系人功能void deletePerson();// 查找联系人功能void findPerson();// 修改联系人功能void modifyPerson();// 清空联系人功能void clearPerson();
};

成员行为实现:(manager.cpp内容)

  1. 显示菜单:void showMenu()
// 实现展示菜单功能
void Manager::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;
}
  1. 得到原来保存联系人数量:void getNum(),在第四步会用到
// 得到原先文件联系人数量
int Manager::getNum()
{ifstream ifs;ifs.open(FILE_NAME, ios::in);int num = 0;string name;    // 联系人姓名int age;        // 联系人年龄int sex;        // 联系人性别,后续1表示男,2表示女string address; // 联系人地址string phone;   // 联系人电话//当人的所有属性被读取到后才可进行num++while (ifs >> name && ifs >> sex && ifs >> age && ifs >> phone && ifs >> address){num++;}ifs.close();return num;
}
  1. 初始化函数:void init()(使通讯录功能正常使用,读取之前保存在person.txt文件中的数据,在第四步也会用到)
// init功能
void Manager::init()
{ifstream ifs;ifs.open(FILE_NAME, ios::in);string name;    // 联系人姓名int age;        // 联系人年龄int sex;        // 联系人性别,后续1表示男,2表示女string address; // 联系人地址string phone;   // 联系人电话int index = 0;while (ifs >> name && ifs >> sex && ifs >> age && ifs >> phone && ifs >> address){this->arr[index] = Person(name, sex, age, phone, address);index++;}
}
  1. 读文件:Manager()(Manager类的默认构造函数,会用到上一步的getNum())
// 文件读取
Manager::Manager()
{// 1.文件未创建ifstream ifs;ifs.open(FILE_NAME, ios::in);if (!ifs.is_open()){isEmpty = true;//文件是否为空标志,是this->num = 0;ifs.close();return;}// 2.文件创建但数据为空char ch;ifs >> ch;if (ifs.eof()){isEmpty = true; // 文件是否为空标志,是this->num = 0;ifs.close();return;}// 3. 文件存在且数据不为空,以既有数据初始化程序isEmpty = false; // 文件是否为空标志,不是this->num = this->getNum();//得到原来保存联系人数量,即第二步this->init();//初始化,即第三步
}
  1. 保存已录入数据:void save()(后面大部分功能都将用到此函数)
// 实现文件写入保存功能
void Manager::save()
{ofstream ofs;ofs.open(FILE_NAME, ios::out);for (int i = 0; i < this->num; i++){ofs << this->arr[i].Name << " "<< this->arr[i].Sex << " "<< this->arr[i].Age << " "<< this->arr[i].Phone << " "<< this->arr[i].Address << endl;}ofs.close();
}
七大功能实现
  1. 退出功能
// 实现退出功能
void Manager::Exit()
{cout << "欢迎下次使用" << endl;exit(0);
}
  1. 添加联系人功能:void addPerson()(添加并同时保存到数组中,再利用save()保存在文件中,实现了一次添加多人功能)
// 实现添加联系人功能
void Manager::addPerson()
{if (num == 1000){cout << "通讯录已满,无法添加" << endl;return;}// 批量添加cout << "请输入添加联系人的数量:" << endl;int addNum; // 要添加的数量cin >> addNum;int i = 1;//从第一个人开始添加while (addNum) // 循环添加{// 添加姓名string name;cout << "请输入第" << i << "名联系人姓名:" << endl;cin >> name;arr[num].Name = name;//num即上次关闭程序保存的人数,此次添加就从其后添加// 添加年龄int age;cout << "请输入联系人年龄:" << endl;cin >> age;arr[num].Age = age;// 添加性别int sex;cout << "请选择联系人性别:" << endl;cout << "1.男" << endl;cout << "2.女" << endl;cin >> sex;if (sex == 1){arr[num].Sex = 1;}else{arr[num].Sex = 2;}// 添加电话string phone;cout << "请输入联系人电话:" << endl;cin >> phone;arr[num].Phone = phone;// 添加地址string address;cout << "请输入联系人地址:" << endl;cin >> address; arr[num].Address = address;i++;//下一个人num++;addNum--;//想要添加的人数即减一cout << "添加成功" << endl;this->save();// 更新职工不为空的标志this->isEmpty = false;}
}
  1. 显示联系人功能:void showPerson()
// 实现显示联系人功能
void Manager::showPerson()
{if (this->isEmpty){cout << "通讯录为空" << endl;return;}for (int i = 0; i < this->num; i++){cout << "姓名:" << this->arr[i].Name << "\t";if (this->arr[i].Sex == 1){cout << "性别:男" << "\t";}else{cout << "性别:女" << "\t";}cout << "年龄:" << this->arr[i].Age << "\t";cout << "电话:" << this->arr[i].Phone << "\t";cout << "地址:" << this->arr[i].Address << "\t" << endl;}
}
  1. 删除联系人功能:void deletePerson()(实质是数据前移)
// 实现删除联系人功能
void Manager::deletePerson()
{if (this->isEmpty){cout << "通讯录为空" << endl;return;}cout << "请输入要删除的联系人姓名:" << endl;string name;cin >> name;int temp = num;for (int i = 0; i < temp; i++){if (this->arr[i].Name == name){for (int j = i; j < this->num - 1; j++){this->arr[j] = this->arr[j + 1];}this->num--;}}if (this->num == temp){cout << "没有找到该联系人" << endl;}else{cout << "删除成功" << endl;}this->save();
}
  1. 查找联系人功能:void findPerson()(根据姓名查找)
// 实现查找联系人功能
void Manager::findPerson()
{if (this->isEmpty){cout << "通讯录为空" << endl;return;}cout << "请输入要查找的联系人姓名:" << endl;string name;cin >> name;for (int i = 0; i < this->num; i++){if (this->arr[i].Name == name){cout << "姓名:" << this->arr[i].Name << "\t";if (this->arr[i].Sex == 1){cout << "性别:男" << "\t";}else{cout << "性别:女" << "\t";}cout << "年龄:" << this->arr[i].Age << "\t";cout << "电话:" << this->arr[i].Phone << "\t";cout << "地址:" << this->arr[i].Address << "\t" << endl;}if (i == this->num - 1){cout << "未找到该联系人" << endl;return;}}cout << "查找成功" << endl;
}
  1. 修改联系人功能:void modifyPerson()
  • 根据姓名修改,首先先显示所有此姓名的人,再从中选择要修改的人
  • 再用Person定义一个临时数组,记录同名的人,根据下标选择想要修改的人
  • 通过比较临时数组中的联系人和通讯录中的联系人来找到要修改的联系人的索引
// 实现修改联系人功能
void Manager::modifyPerson()
{if (this->isEmpty){cout << "通讯录为空" << endl;return;}cout << "选择你要修改的联系人的姓名:" << endl;string name;cin >> name;Person temp[MAX]; // 用Person定义一个小数组,记录同名的人,根据下标选择想要修改的人int index = 0;for (int i = 0; i < this->num; i++){if (arr[i].Name == name){cout << "姓名:" << this->arr[i].Name << "\t";if (this->arr[i].Sex == 1){cout << "性别:男" << "\t";}else{cout << "性别:女" << "\t";}cout << "年龄:" << this->arr[i].Age << "\t";cout << "电话:" << this->arr[i].Phone << "\t";cout << "地址:" << this->arr[i].Address << endl;temp[index] = arr[i];index++;}if (i == this->num - 1){cout << "未找到该联系人" << endl;return;}}cout << "请选择要修改的联系人的序号:" << endl;int NUM;cin >> NUM;int newIndex;for (int i = 0; i < num; i++){if (temp[NUM - 1].Name == arr[i].Name && temp[NUM - 1].Phone == arr[i].Phone && temp[NUM - 1].Address == arr[i].Address && temp[NUM - 1].Age == arr[i].Age && temp[NUM - 1].Sex == arr[i].Sex){newIndex = i; // 找到了要修改的联系人的下标}}cout << "请输入修改后的联系人姓名:" << endl;string newName; // 因为上面已经定义了name,所以这用newName,防重复cin >> newName;arr[newIndex].Name = newName;cout << "请输入修改后的联系人性别:" << endl;cout << "1.男" << endl;cout << "2.女" << endl;int sex;cin >> sex;if (sex == 1){arr[newIndex].Sex = 1;}else{arr[newIndex].Sex = 2;}cout << "请输入修改后的联系人年龄:" << endl;int age;cin >> age;arr[newIndex].Age = age;cout << "请输入修改后的联系人电话:" << endl;string phone;cin >> phone;arr[newIndex].Phone = phone;cout << "请输入修改后的联系人地址:" << endl;string address;cin >> address;arr[newIndex].Address = address;cout << "修改成功" << endl;this->save();
}
  1. 清空通讯录功能
// 清空联系人功能
void Manager::clearPerson()
{if (this->isEmpty){cout << "通讯录为空" << endl;return;}cout << "确定清空通讯录吗?" << endl;cout << "1.确定" << endl;cout << "2.取消" << endl;int choice;cin >> choice;if (choice == 1){this->num = 0;this->isEmpty = true;this->save();cout << "清空成功" << endl;}else{cout << "取消成功" << endl;}
}

到此即实现了完整的通讯录管理系统


http://www.ppmy.cn/ops/105186.html

相关文章

剑侠情缘c#版(游戏源码+资源+工具+程序),百度云盘下载,大小1.68G

剑侠情缘c#版&#xff08;游戏源码资源工具程序&#xff09;&#xff0c;c#开发的&#xff0c;喜欢研究游戏的可以下载看看。亲测可进游戏。 剑侠情缘c#版&#xff08;游戏源码资源工具程序&#xff09;下载地址&#xff1a; 通过网盘分享的文件&#xff1a;【游戏】剑侠情缘c#…

108页PPT分享:华为流程体系及实施方法最佳实践

PPT下载链接见文末~ 华为的流程体系、流程框架及实施方法是一个复杂而精细的系统&#xff0c;旨在确保公司运作的高效性和竞争力。以下是对这些方面的详细描述&#xff1a; 一、华为的流程体系 华为的流程体系是一套全面的管理体系&#xff0c;它涵盖了企业所有的活动&#…

JS设计模式之“分即是合” - 建造者模式

引言 当我们在进行软件编程时&#xff0c;常常会遇到需要创建复杂对象的情况。这些对象可能有多个属性&#xff0c;属性之间存在依赖关系&#xff0c;或需要按照特定的骤来创建。在这种情况下&#xff0c;使用建造者模式&#xff08;Builder Pattern&#xff09;可以提供一种活…

Android 使用原生相机Camera在预览界面进行识别二维码或者图片处理

1 项目需求 最近项目中有个需求:使用原生相机在预览界面进行识别二维码和图片处理。其实这个需求不是很难,难在对预览画面的处理过程。 自己针对这个需求写了一个工具类,便于后续进行复盘,同时也分享给有类似需求的伙伴们。 2 遇到的问题 2.1 二维码识别成功率低 使用…

postgresql数据库创建表分区和分区分区查询失效问题

postgresql数据库创建表分区和分区失效场景 一、前言二、分区表创建1、范围分区&#xff08;Range Partitioning&#xff09;2、列表分区&#xff08;List Partitioning&#xff09;3、hash分区&#xff08;hash Partitioning&#xff09; 三、表分区查询失效问题 一、前言 在…

C++入门基础知识10

C 标识符 C 标识符是用来标识变量、函数、类、模块&#xff0c;或任何其他用户自定义项目的名称。一个标识符以字母 A-Z 或 a-z 或下划线 _ 开始&#xff0c;后跟零个或多个字母、下划线和数字&#xff08;0-9&#xff09;。 C 标识符内不允许出现标点字符&#xff0c;比如 、&…

【C++ Primer Plus习题】8.2

问题: 解答: #include <iostream> using namespace std;typedef struct _CandyBar {string brand;float weight;int hot; }CandyBar;void fill(CandyBar& cb, const char* name"Millennium Munch", double w2.85, int h350) {cb.brand name;cb.weight w…

Redis increment 函数处理并发序列号

1. 创建Spring Boot项目 首先&#xff0c;创建一个新的Spring Boot项目。你可以使用Spring Initializr&#xff08;https://start.spring.io/&#xff09;来生成项目结构。选择以下依赖&#xff1a; Spring WebSpring Data RedisLombok&#xff08;可选&#xff0c;用于简化代…