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

server/2024/10/8 15:46: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/server/111285.html

相关文章

c++ 标准模板库 STL

C 标准模板库&#xff08;STL&#xff0c;Standard Template Library&#xff09;是一个强大的 C 库&#xff0c;包含了一组泛型类和函数&#xff0c;这些类和函数可以用来处理各种数据结构和算法。STL 的主要组成部分包括容器、算法、迭代器和函数对象。 ### STL 的主要组成部…

pyro plate的介绍,plate也能设置cuda pytorch概率编程 贝叶斯神经网络

class plate(name: str, size: Optional[int] None, subsample_size: Optional[int] None, subsample: Optional[torch.Tensor] None, dim: Optional[int] None, use_cuda: Optional[bool] None, device: Optional[str] None)[source] 基元 plate 获取参数存储()→ pyr…

sqli-labs靶场通关攻略(61-65)

Less-61 步骤一&#xff1a;查看数据库 ?id1)) and updatexml(1,concat(1,(select database())),1)-- 步骤二&#xff1a;查看表名 ?id1)) and updatexml(1,concat(1,(select group_concat(table_name) from information_schema.tables where table_schemasecurity)),1)--…

数据分析- 海量数据求中位数

1. 内存中排序法 如果内存足够容纳所有数据&#xff0c;可以将数据加载到内存中&#xff0c;进行排序&#xff0c;然后直接找到中间位置的元素或者中间两个元素求平均值作为中位数。 步骤 加载数据&#xff1a; 将数据读入内存中。数据可以从文件、数据库或其他数据源加载。 排…

英飞凌HSM内核开发-软硬件架构

veHsm硬件和软件架构概述 1. 软件硬件架构 veHsm是一个嵌入式硬件安全模块&#xff0c;它通过硬件提供的安全区域来增强安全性&#xff0c;这个区域包括&#xff1a; 专用核心&#xff1a;负责执行安全操作。安全内存&#xff1a;用于存储敏感数据&#xff0c;如密钥和资产&a…

DP和HDMI的产生根源

HDMI接口是松下、索尼这些电视厂商在2002年联合推出的视频传输接口&#xff0c;HDMI1.0最高带宽达到4.96Gbps。2006推出的HDMI1.3版本最高带宽达到10.2Gbps&#xff0c;经过四年发展&#xff0c;HDMI接口从电视领域逐步拓展到游戏主机、笔记本、摄像机、数码相机等产品上&#…

CentOS7安装docker小记

首先你得需要有一个虚拟机&#xff0c;我的配置如图&#xff1a; 安装docker的工具 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 指定阿里云的仓库 sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.re…

【ffmpeg】转换音频格式

在音频文件所在目录启动终端输入以下 ffmpeg -y -i original.aac target.mp3-y 如果输出文件已经存在&#xff0c;则覆盖它而不询问。 执行完毕后在当前文件夹目录下生成目标文件