首页 > 编程语言 >c++vscode多文件实现通讯录管理系统

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

时间:2024-09-02 18:53:46浏览次数:6  
标签:arr cout vscode void 联系人 c++ int num 通讯录

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;
    }
}

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

标签:arr,cout,vscode,void,联系人,c++,int,num,通讯录
From: https://blog.csdn.net/fast_gowin/article/details/141728588

相关文章

  • IDA反编译dll库时导入C++头文件
    引言有时候,可能因为硬盘损坏等等原因,自己曾经写的动态链接库源码丢失了,幸好对应的头文件得以保留了下来,这个动态链接库主要是某种算法的实现,并没有继承其他的一些类库,比如MFC之类的,而自己对算法的实现已经忘得差不多了,而突然又需要该算法的实现过程,那么有什么办法可以帮助......
  • 【树莓派开发】树莓派GeanyIDE和控制台下C/C++中文乱码问题解决方法
    文章目录情况说明1.设置VS,将文件保存为UTF8编码2.更改GeanyIDE编码设置3.更改树莓派系统设置情况说明之前使用树莓派的时候,遇到了中文乱码的问题。VS2019编译器下写的.c文件,里面的中文注释在树莓派ide上乱码树莓派控制台上,C语言代码输出中文时乱码这里需要调整三个设置来解决该......
  • 【C++】空间配置器
    空间配置器,听起来高大上,那它到底是什么东西呢?1.什么是空间配置器?空间配置器是STL源码中实现的一个小灶,用来应对STL容器频繁申请小块内存空间的问题。他算是一个小型的内存池,以提升STL容器在空间申请方面的效率2.了解空间配置器STL以128个字节为分界线,将空间配置器分为了一级和二级2......
  • C++中namespace的用法
    我们在现实的项目开发中一般会有着大量的代码,而且代码都是多人编写的,也许一个项目会有10个功能,每一个人都要完成一个功能。但是敲过代码的都知道,一般在编写程序的时候如果多人没有实现约定去完成,那就会出现代码冲突的情况,那么,为了解决这样的冲突,我们C++中使用了命名空间namesp......
  • 多重背包问题 模板 C++实现
    问题:有n 种物品和一个容量是c 的背包。第i种物品最多有num[i-1] 件,每件体积是weight[i-1],价值是value[i-1]。求解将哪些物品装入背包,可使物品重量总和不超过背包容量,且价值总和最大。输出最大价值。算法1:三重循环内层循环用于考虑当前物品i可......
  • 2024年华为OD机试E卷- Boss的收入-(Java&c++&Python)
    题目描述:一个XX产品行销总公司,只有一个b0ss,其有若千一级分销,一级分销又有若干二级分销,每个分错只有唯一的上级分销。规定,每个月,下级分销需要将自己的总收入(自已的+下级上交的)每满100元上交15元给自己的上级现给出一组分销的关系,和每个分销的收入,请找出boss并计算出这个boss......
  • C++中不定参数函数的实现方法
    目录一.前言二.代码解析1.模板方式第一种写法第二种写法2.va_list方式三.其他一.前言C++中实现不定参数函数可以采用多种方法,这篇文章讨论不定参数模板和va_list。二.代码解析1.模板方式C++中采用模板来实现不定参数列表,可以有多种编码的方法,这里提供两种方法。......
  • c++ string 与 wstring 互转
    string转wstring:#include<iostream>#include<sstream>#include<locale>#include<string>#include<codecvt>intmain(){std::stringutf8_str="你好,世界!";std::wstring_convert<std::codecvt_utf8<wc......
  • 【C++】C++STL 揭秘:Strng背后的底层逻辑
    C++语法相关知识点可以通过点击以下链接进行学习一起加油!命名空间缺省参数与函数重载C++相关特性类和对象-上篇在上篇介绍string类的使用与理解,本篇将为大家来带关于string的底层实现逻辑,当然这不是一定库里面的实现逻辑。我们设计一个string类是为了在使用string类相关......
  • 命名空间在 C++ 中如何组织和管理代码?,c++中的命名空间是什么意思
    在C++编程中,命名空间(namespace)是组织和管理代码的重要工具。它为程序员提供了一种将代码按逻辑分组的方法,避免名称冲突,特别是在大型项目或使用多个库时显得尤为重要。命名空间可以看作是一个作用域,它包含了标识符(如变量、函数、类等)的集合。当我们在不同的模块中使用相同的标识符......