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

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

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

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

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

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

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

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

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

二、思路

三、功能实现

3.1 person.h封装

c++ 复制代码
#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实现如下:

c++ 复制代码
#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类封装

c++ 复制代码
#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()
c++ 复制代码
// 实现展示菜单功能
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(),在第四步会用到
c++ 复制代码
// 得到原先文件联系人数量
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文件中的数据,在第四步也会用到)
c++ 复制代码
// 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())
c++ 复制代码
// 文件读取
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()(后面大部分功能都将用到此函数)
c++ 复制代码
// 实现文件写入保存功能
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. 退出功能
c++ 复制代码
// 实现退出功能
void Manager::Exit()
{
    cout << "欢迎下次使用" << endl;
    exit(0);
}
  1. 添加联系人功能:void addPerson()(添加并同时保存到数组中,再利用save()保存在文件中,实现了一次添加多人功能)
c++ 复制代码
// 实现添加联系人功能
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()
c++ 复制代码
// 实现显示联系人功能
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()(实质是数据前移)
c++ 复制代码
// 实现删除联系人功能
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()(根据姓名查找)
c++ 复制代码
// 实现查找联系人功能
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定义一个临时数组,记录同名的人,根据下标选择想要修改的人
  • 通过比较临时数组中的联系人和通讯录中的联系人来找到要修改的联系人的索引
c++ 复制代码
// 实现修改联系人功能
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. 清空通讯录功能
c++ 复制代码
// 清空联系人功能
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;
    }
}

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

相关推荐
此生只爱蛋14 分钟前
【手撕排序2】快速排序
c语言·c++·算法·排序算法
blammmp21 分钟前
Java:数据结构-枚举
java·开发语言·数据结构
何曾参静谧34 分钟前
「C/C++」C/C++ 指针篇 之 指针运算
c语言·开发语言·c++
暗黑起源喵40 分钟前
设计模式-工厂设计模式
java·开发语言·设计模式
WaaTong44 分钟前
Java反射
java·开发语言·反射
Troc_wangpeng1 小时前
R language 关于二维平面直角坐标系的制作
开发语言·机器学习
努力的家伙是不讨厌的1 小时前
解析json导出csv或者直接入库
开发语言·python·json
Envyᥫᩣ1 小时前
C#语言:从入门到精通
开发语言·c#
童先生1 小时前
Go 项目中实现类似 Java Shiro 的权限控制中间件?
开发语言·go
lulu_gh_yu1 小时前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法