通讯录管理系统(C++基础 汇总案例)

通讯录管理系统(C++基础 汇总案例)

本案例由前几篇C++基础知识汇总编写完成

  1. C++基础(初识->逻辑运算符)
  2. C++基础 流程控制-选择结构
  3. C++基础 流程控制-循环结构
  4. C++基础 流程控制-跳转语句
  5. C++基础 数组
  6. C++基础 函数
  7. C++基础 指针
  8. C++基础 结构体

一、系统功能需求

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

二、功能实现

1.结构体定义

联系人结构体定义和通讯录结构体定义

```
//联系人信息结构体
struct person 
{
    string name;//姓名
    int sex;//1男,2女
    int age;//年龄
    string phone;//电话
    string addr;//地址
};

//电话薄机构体
struct addrBooks 
{
    struct person manArray[Max];//联系人数组
    int size;//储存人数
};
```
2.主函数

main函数使用while死循环和switch选择结构来实现用户输入数字使用相应的功能,输入0则结束循环,退出系统。

```
int main()
{
    //初始化通讯录
    struct addrBooks ab;
    //初始化人数
    ab.size = 0;

    //初始化输入选择
    int select = 0;
    
    //通过while死循环和switch选择,输入相应数字选择功能,输入0跳出循环结束程序;
    while (true)
    {
        //显示主菜单
        showMenu();
        //用户输入选择功能
        cin >> select;

        switch (select)
        {
            //1、添加联系人
        case 1:
            addPerson(&ab);
            break;
            //2、显示联系人
        case 2:
            showPerson(&ab);
            break;
            //3、查找联系人
        case 3:
            queryPerson(&ab);
            break;
            //4、删除联系人
        case 4:
            deletePerson(&ab);
            break;
            //5、修改联系人
        case 5:
            alterPerson(&ab);
            break;
            //6、清空联系人
        case 6:
            dorpBooks(&ab);
            break;
            //0、退出通讯录
        case 0:
            cout << "欢迎下次使用" << endl;
            system("pause");
            return 0;
            break;
        default:
            break;
        }
    }
}
```
3.封装函数

主要功能函数都通过结构体指针来作为参数,一是可以直接修改实参的值,二是避免了实参对形参值传递时复制大量副本,占用内存。

每一个函数封装完成都要进行测试,直到正确才写下一个功能,避免bug积累。

3.1、主菜单显示
```
void 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;
}
```
3.2、其他常用功能函数

*将其他常用功能封装为函数,避免代码重复

3.2.1、清空屏幕

```
//按下任意键继续,清空屏幕
void clear()
{
    system("pause");//按任意键继续
    system("cls");//屏幕刷新
}
```

3.2.2、打印字段名

```
//打印字段名
void printTitle()
{
    cout << "姓名" << "\t性别" << "\t年龄" << "\t电话" << "\t\t地址" << endl;
}
```

3.2.3、打印联系人信息

```
//打印联系人信息(传入结构体指针和下标)
void print(struct addrBooks* ab,int i)
{
    cout << ab->manArray[i].name
        << "\t"
        << (ab->manArray[i].sex == 1 ? "男" : "女")//通过三目运算符,1打印男,2打印女;
        << "\t"
        << ab->manArray[i].age
        << "\t"
        << ab->manArray[i].phone
        << "\t"
        << ab->manArray[i].addr
        << endl;
}
```

3.2.4、判断联系人是否存在

```
//判断联系人是否存在于通讯录(传入结构体指针和姓名)
int isExist(struct addrBooks* ab, string name)
{
    for (int i = 0; i < ab->size; i++)
    {
        //判断是否联系人是否存在;
        if (name == ab->manArray[i].name)
        {
            return i;//存在返回下标i;
            break;
        }
    }
    return -1;//不存在返回-1;
}
  ```
3.3、添加联系人

首先判断通讯录是否满,其次对于性别和电话输入通过while死循环中嵌套判,来使用户输入正确才进行下一步。

```
//添加联系人
void addPerson(struct addrBooks* ab)
{
    //判断通讯录系统是否已满
    if (ab->size >= 1000)
    {
        cout << "通讯录已经满了,已经不能添加了,如要添加,请删除部分联系人" << endl;
        return;//直接返回空,结束函数
    }
    else
    {
        //**输入姓名**
        string name;
        cout << "请输入姓名:" << endl;
        cin >> name;
        ab->manArray[ab->size].name = name;

        //**输入性别**
        //1代表男,2代表女
        int sex;
        
        //通过while死循环,输入正确跳出循环,错误就重新输入;
        while (true)
        {
            cout << "请输入性别" << "(1-->男,2-->女)" << endl;
            cin >> sex;
            //判断是否为1或者2,不正确就报错重新输入
            if (sex == 1 || sex == 2)
            {
                ab->manArray[ab->size].sex = sex;
                break;
            }
            cout << "输入错误,请重新输入" << endl;
        }

        //**输入年龄**
        int age;

        //通过while死循环,输入正确跳出循环,错误就重新输入;
        while (true)
        {
            cout << "请输入年龄" << endl;
            cin >> age;

            //判断年龄是否为1到120岁之间;
            if (age >= 1 && age <= 120)
            {
                ab->manArray[ab->size].age = age;
                break;
            }
            cout << "输入错误,请重新输入" << endl;
        }

        //**输入电话号码**
        string phone;
        
        //通过while死循环,输入正确跳出循环,错误就重新输入;
        while (true)
        {
            cout << "请输入电话号码" << endl;
            cin >> phone;

            //记录输入电话号码的长度
            int len;
            //strlen只能统计c风格的字符串长度,使用.c_str()转换
            len = strlen(phone.c_str());

            //判断是否符合电话号码长度11位
            if (  len == 11 )
            {
                //通过循环和ASCII码表判断输入是否为数字
                for (int i = 0; i < 11; i++)
                {
                    if (phone[i] >= 48 && phone[i] <= 57)
                    {
                        //当11位数全满足时数字时,结束循环,成功输入电话号码
                        if (i == 10)
                        {
                            ab->manArray[ab->size].phone = phone;
                        }   
                    }
                    else
                    {
                        //当有一位不是数字时,直接跳到FLAG输出错误,重新输入
                        goto FLAG;
                    }
                }
                break;
            }
            FLAG: 
            cout << "输入错误,请重新输入" << endl;
        }

        //**输入地址**
        string addr;
        cout << "请输入地址:" << endl;
        cin >> addr;
        ab->manArray[ab->size].addr = addr;

        //全部输入正确提升添加成功
        cout << "添加成功" << endl;

        ab->size++;//电话簿总人数+1

        clear();//按下任意键清屏
    }
}
```
3.4、显示联系人
```
//显示联系人
void showPerson(struct addrBooks* ab)
{
    //判断是否电话簿为空
    if (ab->size == 0)
    {
        cout << "电话薄为空,请添加联系人" << endl;
    }
    else
    {
        printTitle();//输出姓名,性别...地址这些字段名
        for (int i = 0; i < ab->size; i++)
        {
            print(ab, i);//输出指定下标的联系人信息
        }
    }

    clear();//按下任意键清屏
}
```
3.5、查询联系人
```
//查询联系人
void queryPerson(struct addrBooks* ab)
{
    //判断是否电话簿为空
    if (ab->size == 0)
    {
        cout << "电话薄为空,请添加联系人" << endl;
    }

    else 
    {
        cout << "请输入姓名" << endl;
        string name;
        cin >> name;
        
        //判断联系人是否存在,存在返回联系人结构体数组下标,不存在返回-1;
        int rt = isExist(ab, name);

        //如果不存在显示查无此人;
        if (rt == -1)
        {
            cout << "查无此人" << endl;
        }
        //存在,输出联系人信息
        else
        {
            printTitle();//输出姓名,性别...地址这些字段名
            print(ab, rt);//输出指定下标的联系人信息
        }
    }
    clear();//按下任意键清屏
}
```
3.6、删除联系人
```
//删除联系人
void deletePerson(struct addrBooks* ab)
{
    // 判断是否电话簿为空
    if (ab->size == 0)
    {
        cout << "电话薄为空,请添加联系人" << endl;
    }

    else
    {
        cout << "请输入您要删除联系人的姓名" << endl;
        string name;
        cin >> name;
        
        //判断联系人是否存在,存在返回联系人结构体数组下标,不存在返回-1;
        int rt = isExist(ab, name);
        
        //如果不存在显示查无此人;
        if (rt == -1)
        {
            cout << "查无此人" << endl;
            return;
        }
        //存在,将此联系人结构体数组之后的数据全部前移
        else
        {
            for (int i = rt; i < ab->size; i++)
            {
                ab->manArray[i] = ab->manArray[i + 1];//数组前移
            }
            ab->size--;//电话簿总人数-1

            cout << "删除成功!" << endl;
        }
    }
    clear();//按下任意键清屏
}
```
3.7、修改联系人
```
//修改联系人
void alterPerson(struct addrBooks* ab)
{
    if (ab->size == 0)
    {
        cout << "电话薄为空,请添加联系人" << endl;
    }
    else
    {
        cout << "请输入您要修改联系人的姓名" << endl;
        string name;
        cin >> name;

        //判断联系人是否存在,存在返回联系人结构体数组下标,不存在返回-1;
        int rt = isExist(ab, name);

        //如果不存在显示查无此人;
        if (rt == -1)
        {
            cout << "查无此人" << endl;
            return;
        }

        //存在,使用添加联系人中的逻辑进行输入修改信息,可注释可参考添加联系人函数
        else
        {
            //输入姓名
            string name;
            cout << "请输入姓名:" << endl;
            cin >> name;
            ab->manArray[rt].name = name;

            //输入性别
            //1代表男,2代表女
            int sex;
            while (true)
            {
                cout << "请输入性别" << "(1-->男,2-->女)" << endl;
                cin >> sex;
                if (sex == 1 || sex == 2)
                {
                    ab->manArray[rt].sex = sex;
                    break;
                }
                cout << "输入错误,请重新输入" << endl;
            }

            //输入年龄
            int age;
            while (true)
            {
                cout << "请输入年龄" << endl;
                cin >> age;
                if (age >= 1 && age <= 120)
                {
                    ab->manArray[rt].age = age;
                    break;
                }
                cout << "输入错误,请重新输入" << endl;
            }

            //输入电话号码
            string phone;

            while (true)
            {
                cout << "请输入电话号码" << endl;
                cin >> phone;

                //记录输入电话号码的长度
                int len;
                //strlen只能统计c风格的字符串长度,使用.c_str()转换
                len = strlen(phone.c_str());

                if (len == 11)
                {
                    //通过ASCII码表判断输入是否为数字
                    for (int i = 0; i < 11; i++)
                    {
                        if (phone[i] >= 48 && phone[i] <= 57)
                        {
                            //当11位数全满足时数字时,结束循环,成功输入电话号码
                            if (i == 10)
                            {
                                ab->manArray[rt].phone = phone;
                            }
                        }
                        else
                        {
                            //当有一位不是数字时,直接跳到FLAG输出错误,重新输入
                            goto FLAG;
                        }
                    }
                    break;
                }
            FLAG:
                cout << "输入错误,请重新输入" << endl;
            }

            //输入地址
            string addr;
            cout << "请输入地址:" << endl;
            cin >> addr;
            ab->manArray[rt].addr = addr;

            cout << "修改成功" << endl;
        }
    }
    clear();//按下任意键清屏
}
```
3.8、清空联系人
``` 
//清空联系人
void dorpBooks(struct addrBooks* ab)
{
    ab->size = 0;//将结构体中的记录人数清0,做逻辑清空操作;
    cout << "通讯录已清空!!" << endl;
    clear();//按下任意键清屏
}
```

三、代码示例

将上面所有函数组合起来,就完成了通讯录管理系统

```
#include<iostream>
#include<string>
using namespace std;
//通讯录管理系统

//定义宏常量电话簿人数最大值1000
#define Max 1000

//联系人信息结构体
struct person 
{
    string name;//姓名
    int sex;//1男,2女
    int age;//年龄
    string phone;//电话
    string addr;//地址
};

//电话薄机构体
struct addrBooks 
{
    struct person manArray[Max];//联系人数组
    int size;//储存人数
};

//判断联系人是否存在于通讯录(传入结构体指针和姓名)
int isExist(struct addrBooks* ab, string name)
{
    for (int i = 0; i < ab->size; i++)
    {
        //判断是否联系人是否存在;
        if (name == ab->manArray[i].name)
        {
            return i;//存在返回下标i;
            break;
        }
    }
    return -1;//不存在返回-1;
}

//打印字段名
void printTitle()
{
    cout << "姓名" << "\t性别" << "\t年龄" << "\t电话" << "\t\t地址" << endl;
}

//打印联系人信息(传入结构体指针和下标)
void print(struct addrBooks* ab,int i)
{
    cout << ab->manArray[i].name
        << "\t"
        << (ab->manArray[i].sex == 1 ? "男" : "女")//通过三目运算符,1打印男,2打印女;
        << "\t"
        << ab->manArray[i].age
        << "\t"
        << ab->manArray[i].phone
        << "\t"
        << ab->manArray[i].addr
        << endl;
}

//按下任意键继续,清空屏幕
void clear()
{
    system("pause");//按任意键继续
    system("cls");//屏幕刷新
}

//显示菜单
void 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;
}

//添加联系人
void addPerson(struct addrBooks* ab)
{
    //判断通讯录系统是否已满
    if (ab->size >= 1000)
    {
        cout << "通讯录已经满了,已经不能添加了,如要添加,请删除部分联系人" << endl;
        return;//直接返回空,结束函数
    }
    else
    {
        //**输入姓名**
        string name;
        cout << "请输入姓名:" << endl;
        cin >> name;
        ab->manArray[ab->size].name = name;

        //**输入性别**
        //1代表男,2代表女
        int sex;
        
        //通过while死循环,输入正确跳出循环,错误就重新输入;
        while (true)
        {
            cout << "请输入性别" << "(1-->男,2-->女)" << endl;
            cin >> sex;
            //判断是否为1或者2,不正确就报错重新输入
            if (sex == 1 || sex == 2)
            {
                ab->manArray[ab->size].sex = sex;
                break;
            }
            cout << "输入错误,请重新输入" << endl;
        }

        //**输入年龄**
        int age;

        //通过while死循环,输入正确跳出循环,错误就重新输入;
        while (true)
        {
            cout << "请输入年龄" << endl;
            cin >> age;

            //判断年龄是否为1到120岁之间;
            if (age >= 1 && age <= 120)
            {
                ab->manArray[ab->size].age = age;
                break;
            }
            cout << "输入错误,请重新输入" << endl;
        }

        //**输入电话号码**
        string phone;
        
        //通过while死循环,输入正确跳出循环,错误就重新输入;
        while (true)
        {
            cout << "请输入电话号码" << endl;
            cin >> phone;

            //记录输入电话号码的长度
            int len;
            //strlen只能统计c风格的字符串长度,使用.c_str()转换
            len = strlen(phone.c_str());

            //判断是否符合电话号码长度11位
            if (  len == 11 )
            {
                //通过循环和ASCII码表判断输入是否为数字
                for (int i = 0; i < 11; i++)
                {
                    if (phone[i] >= 48 && phone[i] <= 57)
                    {
                        //当11位数全满足时数字时,结束循环,成功输入电话号码
                        if (i == 10)
                        {
                            ab->manArray[ab->size].phone = phone;
                        }   
                    }
                    else
                    {
                        //当有一位不是数字时,直接跳到FLAG输出错误,重新输入
                        goto FLAG;
                    }
                }
                break;
            }
            FLAG: 
            cout << "输入错误,请重新输入" << endl;
        }

        //**输入地址**
        string addr;
        cout << "请输入地址:" << endl;
        cin >> addr;
        ab->manArray[ab->size].addr = addr;

        //全部输入正确提升添加成功
        cout << "添加成功" << endl;

        ab->size++;//电话簿总人数+1

        clear();//按下任意键清屏
    }
}

//显示联系人
void showPerson(struct addrBooks* ab)
{
    //判断是否电话簿为空
    if (ab->size == 0)
    {
        cout << "电话薄为空,请添加联系人" << endl;
    }
    else
    {
        printTitle();//输出姓名,性别...地址这些字段名
        for (int i = 0; i < ab->size; i++)
        {
            print(ab, i);//输出指定下标的联系人信息
        }
    }

    clear();//按下任意键清屏
}

//查询联系人
void queryPerson(struct addrBooks* ab)
{
    //判断是否电话簿为空
    if (ab->size == 0)
    {
        cout << "电话薄为空,请添加联系人" << endl;
    }

    else 
    {
        cout << "请输入姓名" << endl;
        string name;
        cin >> name;
        
        //判断联系人是否存在,存在返回联系人结构体数组下标,不存在返回-1;
        int rt = isExist(ab, name);

        //如果不存在显示查无此人;
        if (rt == -1)
        {
            cout << "查无此人" << endl;
        }
        //存在,输出联系人信息
        else
        {
            printTitle();//输出姓名,性别...地址这些字段名
            print(ab, rt);//输出指定下标的联系人信息
        }
    }
    clear();//按下任意键清屏
}

//删除联系人
void deletePerson(struct addrBooks* ab)
{
    // 判断是否电话簿为空
    if (ab->size == 0)
    {
        cout << "电话薄为空,请添加联系人" << endl;
    }

    else
    {
        cout << "请输入您要删除联系人的姓名" << endl;
        string name;
        cin >> name;
        
        //判断联系人是否存在,存在返回联系人结构体数组下标,不存在返回-1;
        int rt = isExist(ab, name);
        
        //如果不存在显示查无此人;
        if (rt == -1)
        {
            cout << "查无此人" << endl;
            return;
        }
        //存在,将此联系人结构体数组之后的数据全部前移
        else
        {
            for (int i = rt; i < ab->size; i++)
            {
                ab->manArray[i] = ab->manArray[i + 1];//数组前移
            }
            ab->size--;//电话簿总人数-1

            cout << "删除成功!" << endl;
        }
    }
    clear();//按下任意键清屏
}

//修改联系人
void alterPerson(struct addrBooks* ab)
{
    if (ab->size == 0)
    {
        cout << "电话薄为空,请添加联系人" << endl;
    }
    else
    {
        cout << "请输入您要修改联系人的姓名" << endl;
        string name;
        cin >> name;

        //判断联系人是否存在,存在返回联系人结构体数组下标,不存在返回-1;
        int rt = isExist(ab, name);

        //如果不存在显示查无此人;
        if (rt == -1)
        {
            cout << "查无此人" << endl;
            return;
        }

        //存在,使用添加联系人中的逻辑进行输入修改信息,可注释可参考添加联系人函数
        else
        {
            //输入姓名
            string name;
            cout << "请输入姓名:" << endl;
            cin >> name;
            ab->manArray[rt].name = name;

            //输入性别
            //1代表男,2代表女
            int sex;
            while (true)
            {
                cout << "请输入性别" << "(1-->男,2-->女)" << endl;
                cin >> sex;
                if (sex == 1 || sex == 2)
                {
                    ab->manArray[rt].sex = sex;
                    break;
                }
                cout << "输入错误,请重新输入" << endl;
            }

            //输入年龄
            int age;
            while (true)
            {
                cout << "请输入年龄" << endl;
                cin >> age;
                if (age >= 1 && age <= 120)
                {
                    ab->manArray[rt].age = age;
                    break;
                }
                cout << "输入错误,请重新输入" << endl;
            }

            //输入电话号码
            string phone;

            while (true)
            {
                cout << "请输入电话号码" << endl;
                cin >> phone;

                //记录输入电话号码的长度
                int len;
                //strlen只能统计c风格的字符串长度,使用.c_str()转换
                len = strlen(phone.c_str());

                if (len == 11)
                {
                    //通过ASCII码表判断输入是否为数字
                    for (int i = 0; i < 11; i++)
                    {
                        if (phone[i] >= 48 && phone[i] <= 57)
                        {
                            //当11位数全满足时数字时,结束循环,成功输入电话号码
                            if (i == 10)
                            {
                                ab->manArray[rt].phone = phone;
                            }
                        }
                        else
                        {
                            //当有一位不是数字时,直接跳到FLAG输出错误,重新输入
                            goto FLAG;
                        }
                    }
                    break;
                }
            FLAG:
                cout << "输入错误,请重新输入" << endl;
            }

            //输入地址
            string addr;
            cout << "请输入地址:" << endl;
            cin >> addr;
            ab->manArray[rt].addr = addr;

            cout << "修改成功" << endl;
        }
    }
    clear();//按下任意键清屏
}

//清空联系人
void dorpBooks(struct addrBooks* ab)
{
    ab->size = 0;//将结构体中的记录人数清0,做逻辑清空操作;
    cout << "通讯录已清空!!" << endl;
    clear();//按下任意键清屏
}

int main()
{
    //初始化通讯录
    struct addrBooks ab;
    //初始化人数
    ab.size = 0;

    //初始化输入选择
    int select = 0;
    
    //通过while死循环和switch选择,输入相应数字选择功能,输入0跳出循环结束程序;
    while (true)
    {
        //显示主菜单
        showMenu();
        //用户输入选择功能
        cin >> select;

        switch (select)
        {
            //1、添加联系人
        case 1:
            addPerson(&ab);
            break;
            //2、显示联系人
        case 2:
            showPerson(&ab);
            break;
            //3、查找联系人
        case 3:
            queryPerson(&ab);
            break;
            //4、删除联系人
        case 4:
            deletePerson(&ab);
            break;
            //5、修改联系人
        case 5:
            alterPerson(&ab);
            break;
            //6、清空联系人
        case 6:
            dorpBooks(&ab);
            break;
            //0、退出通讯录
        case 0:
            cout << "欢迎下次使用" << endl;
            system("pause");
            return 0;
            break;
        default:
            break;
        }
    }
}
```

四、测试数据

```
1
22
13333333333
北京

李四
1
24
14444444444
湖北

王五
2
24
15555555555
四川
```
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。