Javer 学 c++(十):通讯录篇

85 阅读5分钟

总览

用前面的知识实现一个通讯录管理系统,代码自测通过

v1.0:

效率问题:使用数组实现了基本的功能,没有考虑性能问题,用链表+哈希应该会更快(类 lru)。

引用问题:里面区分了值传递和引用传递,但是实际上值传递每次都需要复制结构体,都用引用传递会更节省空间。

未解决问题:没有找到清空终端的命令(本来想在每次命令之后清空终端),试了 clear 并不可以,不知道是否 Clion 自带终端不支持的问题

代码风格:比较粗糙,可能有地方不符合标准开发规范,如有发现感谢指点

系统需求

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

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

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

需求撰写

基础结构

这里面其实主要有两个对象,一个是通讯录,一个是联系人

#include <iostream>
using namespace std;
#define MAX 1000

struct Person {
    string name;
    string gender;
    int age;
    string phoneNumber;
    string address;
};

struct Books {
    Person personArray[MAX]; // 人员名单
    int size=0; // 通讯录中人员个数,初始化为0,就不用在创建的时候初始化了
};

主界面部分

样式

image.png

需求分析

展示:因为只用到简单的代码,这里直接硬编码输出了

接受输入:这里用 cin 来接入一个值,对应的是上面的功能

特殊case:如果输入非法,默认为退出

调用对应功能:如果一直调用功能系统不会退出,这里这里需要用一个 while 来持续接收输入,除非接收到了 0 或者非法才会退出 while 循环

需要注意 1-6 的功能函数中,哪些需要传指针,哪些需要传值

代码实现

void printMenu() {
    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;
}
int main() {

    // 输入值
    int style;

    Books book;

    Person * p1 = book.personArray;
    int * p2 = &book.size;

    while (true) {
        // 每次开始时打印功能菜单
        printMenu();
        cin >> style;

        switch (style) {
            case 1:
                //  1. 添加联系人
                add(p1, p2);
                break;
            case 2:
                // 2. 显示联系人
                show(book.personArray, book.size);
                break;
            case 3:
                // 3. 删除联系人
                del(p1, p2);
                break;
            case 4:
                // 4. 查找联系人
                find(p1, book.size);
                break;
            case 5:
                // 5. 修改联系人
                update(p1, book.size);
                break;
            case 6:
                // 6. 清空联系人
                clean(p2);
                break;
            case 0:
                // 0. 退出通讯录
                cout << "欢迎下次使用" <<  endl;
                return 0;
            default:
                return 0;
        }
        // 暂停等待用户查看结果
        cout << "请按任意键继续.....";
        cin.ignore();
        cin.get();
    }

}

添加功能

因为人员和 size 都要变化,所以需要都传指针

case:需要判断是否超出容量

void add(Person * personArray, int * size) {

    // case 判断:是否满了
    if (*size >= MAX) {
        cout << "通讯录已满,无法添加";
        return;
    }

    string name;
    string gender;
    int age ;
    string phoneNumber;
    string address;

    cout << "Please enter your name: ";
    cin >> name;
    cout << "Please enter your gender: ";
    cin >> gender;
    cout << "Please enter your age: ";
    cin >> age;
    cout << "Please enter your phone number: ";
    cin >> phoneNumber;
    cout << "Please enter your address: ";
    cin >> address;

    Person person = {name, gender, age, phoneNumber, address};

    // 添加人员
    int index = 0;
    while (index < * size) {
        personArray++;
        index += 1;
    }
    *personArray = {name, gender, age, phoneNumber, address};

    // 通讯录人员个数加一
    * size += 1;

    cout << "添加成功" << endl;
}

显示功能

遍历并打印即可

这里注意因为不涉及到修改,所以直接值传递即可,无需指针

void show(Person personArray[], int size) {

    for (int i = 0; i < size; i++) {
        cout << "姓名:" + personArray[i].name<< "   " << "性别:" + personArray[i].gender << "   ";
        cout << "年龄:" << personArray[i].age << "   ";
        cout << "电话:" + personArray[i].phoneNumber << "   " << "地址:" + personArray[i].address << "   " << endl;
    }
}

删除功能

这里就不考虑性能了,先用数组挪动实现,注意 size 要减一

void del(Person * personArray, int * size) {

    string name;

    cout << "请输入要删除的用户姓名:";
    cin >> name;

    for (int i = 0; i < * size; i++) {
        if (personArray[i].name == name) {
            // 后面的全部前移
            for (int j = i; j < *size; j++) {
                personArray[j] = personArray[j + 1];
            }
            cout << "删除成功" << endl;
            *size -= 1;
            return;
        }
    }

    cout << "未发现该用户!" << endl;
}

查找功能

同样的便利查找,也不需要传递指针

void find(Person personArray[], int size) {

    string name;

    cout << "请输入要查找的用户姓名:";
    cin >> name;

    for (int i = 0; i < size; i++) {
        if (personArray[i].name == name) {
            cout << "姓名:" + personArray[i].name<< "   " << "性别:" + personArray[i].gender << "   ";
            cout << "年龄:" << personArray[i].age << "   ";
            cout << "电话:" + personArray[i].phoneNumber << "   " << "地址:" + personArray[i].address << "   " << endl;
            return;
        }
    }

    cout << "未发现该用户!" << endl;
}

修改功能

void update(Person * personArray, int size) {
    string name;

    cout << "请输入要修改的用户姓名:";
    cin >> name;

    for (int i = 0; i < size; i++) {
        if (personArray[i].name == name) {

            cout << "Please enter your name: ";
            cin >> name;
            personArray[i].name = name;

            string gender;
            cout << "Please enter your gender: ";
            cin >> gender;
            personArray[i].gender = gender;

            int age ;
            cout << "Please enter your age: ";
            cin >> age;
            personArray[i].age = age;

            string phoneNumber;
            cout << "Please enter your phone number: ";
            cin >> phoneNumber;
            personArray[i].phoneNumber = phoneNumber;

            string address;
            cout << "Please enter your address: ";
            cin >> address;
            personArray[i].address = address;

            cout << "修改成功!" << endl;
            return;
        }
    }
    cout << "未发现该用户!" << endl;
}

清空功能

逻辑清空,直接 size 归零即可

void clean(int * size) {
    *size = 0;
    cout << "通讯录已清空!" << endl;
}