0基础学C++ | 第09天 | 基础知识 | 结构体指针 | switch结构 | 通讯管理系统案例练习

前言

这个案例相当于是对前面所学的结构体、数组、switch结构等知识进行的一个总结

功能实现

该案例是要求完成一个通讯管理系统,包括添加联系人、查找联系人、修改联系人信息等能够。通讯录最多联系人不能超过1000,因为在本案例中通讯录涉及两个数据类型(一个是联系人(结构体数组),另一个是联系人的数量(int型)),所以用结构体数据类型来构建通信录这个变量,

另外,联系人涉及到姓名、性别、电话号码等多个数据类型,同时,联系人有多个,所以采用结构体数组类型来构建联系人,最终采用结构体嵌套的方式来设计在这个管理系统的变量,定义好变量后,就开始封装各个功能函数(例如删除、查找、修改等)。下面就是具体的实现代码。

创建联系人结构体

首先构建联系人结构体,该结构体包含姓名、性别、年龄(这里用1表示女性,2表示男性)、电话号码、家庭地址等属性。

结构体的创建语法:

struct 结构体名 { 结构体成员列表 };

//创建联系人结构体
struct Person
{
    string name;
    int m_Sex; //1 男 2 女
    int m_Age;
    string m_Phone;
    string m_Addr;
};

创建通讯录结构体

通讯录结构体中的成员主要就是联系人以及联系人的数量,联系人也是一个结构体,它是嵌入在通讯录结构体中的,这里的 struct person就相当于是一个数据类型(结构体类型)personArray就是变量名,这里就是一个结构体数组类型的数据 ,personArray这个变量就包含了其Person结构体中的所有元素。

//创建通讯录结构体
struct Addressbooks
{
    struct Person personArray[MAX];//通讯录中保存的联系人数组
    int m_Size;//通讯录中人员个数
};

显示菜单 

我们首先要写个菜单来供用户选择,这个显示菜单就是单纯的显示有哪些功能,具体实际的选择功能要使用下面的switch来实现。这里一共实现了7个功能选项,只需要在页面打印出每个选项的就可以。

//首先是显示菜单功能
//创建一个函数来显示菜单功能
 void showMenu()
{
    cout << "1、添加联系人" << endl;
    cout << "2、显示联系人" << endl;
    cout << "3、删除联系人" << endl;
    cout << "4、修改联系人" << endl;
    cout << "5、查找联系人" << endl;
    cout << "6、清空联系人" << endl;
    cout << "0、推出通讯录" << endl;
}

选项功能实现以及推出功能 (使用switch)

要是实现更具选项的不同,进入不同的功能,就要用到switch,例如当我输入1时,就进行添加联系人操作,选择0时,就退出整个通讯录。

这里的退出机制,就用了前面讲的system("pause"),这条语句是命令程序运行到这一步停止的语句。 另外这里的关于管理系统最多只能1000人的数量,采用了宏定义,因为这样方便系统的维护,如果最多可以有2000人,这时就只用改其前面宏定义的部分

#include<iostream>
using namespace std;
#include<string>

#define MAX 1000 //通讯录联系人数最多为1000 用宏定义是为了方便维护

int main()
{

    //搭建选择选项,这里用switch来判断多种情况选一种
    //首先定义一个输入选择的变量  
    int select = 0;
    cin >> select;

    //为了每次都能返回菜单,所以需要一个循环,只有当输入0的时候才会推出这个
    while(ture)
    {
        switch(select)
        {
            case 1:     //1、添加联系人
                addPerson(&abs); //利用地址传递,可以修饰实参
                break;
            case 2:    //2、显示联系人
                break;
            case 3:    //3、删除联系人
                break;

            case 4:    //4、修改联系人
                break;
    
            case 5:    //5、查找联系人
                break;

            case 6:    //6、清空联系人
                break;

            case 0:    //0、推出通讯录
                cout << "欢迎下次使用"<<endl;
                systrm("pause");
                return 0;
                break;
            default:
                break;
        }  
    }  

    syetrm("pause");
    return 0;

}

添加联系人 

封装一个添加联系人的函数,函数传入的参数是整个通讯录结构体的地址,这里为什么是指针呢,因为结构体指针才能修改实参。Addressbook * abs 是一个用指针接收的参数,abs 是我们创建的结构体变量,这个变量他指向任何一个Addressbook类型的结构体,同时,使用  ->  符号来取得Addressbook的一个成员 (我也还没搞明白结构体指针)

定义了结构体:

struct Person{ ... }; //联系人结构体

struct  Addressbook //通讯录结构体

{

       struct Person personArray[MAX]; 

};


Addressbooks abs;//创建结构体变量

void addPerson(Addressbooks * abs)  //定义的添加联系人的函数,

int age = addPerson(&abs)//传递过去, &取地址

abs->personArray[abs->m_Size].m_Name = name;//获取Addressbook中personArray的第m_Size个m_Name成员,并赋予它name值

添加联系人前 ,首先我们要进行判断通讯录人数是否满了(也就是达到了1000人),所以对m_Size(m_Size是通讯录的人数)进行判断是否等于MAX(MAX就是我们宏定义的1000),如果没满,就进行添加操作,包括添加姓名、性别、年龄等,这里其实就是对我们通讯录结构体中的联系人变量(personArray)进行实例化,实例化方式就是通过->符号来获取联系人结构体里的每个成员,并赋值。添加完成之后,不要忘了更新通讯录的人数,也就是更新m_Size(因为添加一个人,m_Size就少一个,所以是 m_Size - - ),最后使用 system("cls")语句来清屏。

//封装添加联系人函数
void addPerson(Addressbooks * abs)
{
    if(abs->m_Size==MAX)
    {
        cout << "通讯录已满,无法添加 "<< endl;
    }
    else
    {
        //添加具体联系人
        //姓名
        string name;
        cout << "请输入姓名:"<<endl;
        cin >> name;
        abs->personArray[abs->m_Size].m_name = name;

        //性别
        int sex == 0;
        cout << "请输入性别:"<<endl;
        cout << "1 -- 男"<<endl;
        cout << "2 -- 女"<<endl;
      
        while(ture)
        {  
            cin >> sex;
            if(sex == 1 || sex == 2)
            {
                   abs->personArray[abs->m_Size].m_sex = sex;
                   break;
             }
             cout << "输入有误,请重新输入"<<endl;
        }

        //年龄
        int age == 0;
        cout << "请输入年龄:"<<endl;
        cin >> age;
        abs->personArray[abs->m_Size].m_age = age;

        //电话
        string phone;
        cout << "请输入电话:"<<endl;
        cin >> phone;
        abs->personArray[abs->m_Size].m_phone = phone;

        //住址
        string address;
        cout << "请输入家庭住址:"<<endl;
        cin >> address
        abs->personArray[abs->m_Size].m_Addr = address;
        
        //更新人数
        abs->m_Size++;
        cout <<"添加成功"<< endl;
        system("cls"); //清屏操作
    }
}

显示联系人 

添加联系人后,我们可以选择对联系人进行显示,当然没添加也可以进行显示,那么在显示之前就需要判断通讯录的人是否为空,也就是m_Size是否为0,如果不是我们就依次打印联系人的信息,因为不只一个联系人 所以我们要使用for循环来依次打印,注意:在性别那一行,因为我们规定的是1为女 2为男 为了方便,所以用了 a?b:c这个运算符 (如果a为真则取b 否则取c)。


​//封装显示联系人函数
int showPserson(Addressbook * abs)
{
    //判断通讯录中人数是否为0
    //如果不为空,就显示联系人的信息
    if(bas->personArray[i].m_Size == 0)
    {
        cout << "通讯录为空" << endl; //找到了,返回这个人在数组中的位置
    }
    else
    {
        for(int i = 0; i < abs->m_Size;i++)
        {
            
            cout << "姓名:" << abs->personArray[i].m_Name << \t;
            cout << "性别:" << abs->personArray[i].m_Sex ==1?"女":"男"<< \t;
            cout << "年龄:" << abs->personArray[i].m_Age << \t;
            cout << "电话:" << abs->personArray[i].m_Phone << \t;
            cout << "住址:" << abs->personArray[i].m_Address << endl;
        }
    }
   
    system("pause");
    system("cls");
  
}

检测联系人是否存在

检测联系人是否存在先对来说就要简单很多,只需要判断输入的名词和数组里的名字是否相等。

​
​//封装检测联系人是否在函数,如果存在 返回联系人在数组中的具体位置,如果不存在,则返回-1
int isEist(Addressbook * abs,string name)
{
    for(int i = 0; i < abs->m_Size;i++)
    {
        if(bas->personArray[i].m_Name == name)
        {
            return i; //找到了,返回这个人在数组中的位置
        }
    }

    system("pause");
    system("cls");
  
}

 实现删除指定的联系人

删除联系人需要先判断联系人是否存在,这里需要用到上面的函数isEist,如果存在,我们只需要找到该名字的下标(m_Szie)然后用后面的数据将前面的数据进行覆盖就OK了,其实就是将 i+1的值赋给 i 就好了。

//创建删除联系人函数
void deletePerson(Addressbooks *abs)
{
    cout <<"请输入要删除的人的名字:"<< endl;
    string name;
    cin >> name;

    //-1没查到,1 查到了
    int ret = isExist(abs,name)
    if(ret != -1)
    {
        //查找到人,进行删除
        for(int i = 0; i < abs->m_Size)
        {    
            //数据前移
            abs->personArray[i] = abs->personArray[i+1];
        }
        abs->m_Size--;    //更新通讯录联系人的人数
        cout << "删除成功" << endl;
        
    }
    else
    {
        cout << " 杳无此人" << endl;
        system("pause");
        system("cls");
    }
} 

实现查找联系人功能

查找联系人也需要判断联系人是否存在,然后利用姓名的数组下标 来获取其他的信息(性别、年龄等)

//封装查找函数
void findPerson(Addressbook * abs)
{
     cout << "请输入查找联系人的姓名:" <<endl;
    string name;
    cin name;
  
    //-1没查到,1 查到了
    int ret = isExist(abs,name)

    if(ret != -1)
    {
        //查找到人,输出相关信息
        cout << "姓名:" << abs->personArray[ret].m_Name << endl;
        cout << "性别:" << abs->personArray[ret].m_Sex << endl;
        cout << "年龄:" << abs->personArray[ret].m_Age << endl;
        cout << "电话:" << abs->personArray[ret].m_Phone << endl;
        cout << "住址:" << abs->personArray[ret].m_Address << endl;
      
    }
    else
    {
        cout << " 杳无此人" << endl;
    }
    system("pause");
    system("cls");  
}

实现修改联系人

同样,修改联系人也需要判断联系人是否存在,然后利用联系人姓名的数组下标来修改联系人的其他信息,修改信息,只需要将输入的数据赋值给原先的值就可以了,这里只是性别那需要进行判断,只能输入 1或2,属于其他的话是没有效的。

​//封装修改函数
void modifyPerson(Addressbook * abs)
{
    cout << "请输入修改联系人的姓名:" <<endl;
    string name;
    cin name;
  
    //-1没查到,1 查到了
    int ret = isExist(abs,name)

    if(ret != -1)  //查找到人,修改相关信息
    {
        //修改姓名
        string name;
        cout << "请输入姓名:" << endl;
        cin >> name;
        abs->personArray[ret].m_Name = name;

        //修改性别
        cout << "请输入性别:" << endl;
        cout << "1---女" << endl;
        cout << "2---男" << endl;
        int sex= 0;
        while(true)
        { 
            cin >> sex;
            if(sex == 1 || sex == 2)
            {
               abs->personArray[ret].m_Sex = sex;
               break; 
            }
            else
            {
                 cout << "输入有误,请重新输入年龄:" << endl;
            }
        
        }
       
        //修改年龄
        cout << "请输入年龄:" << endl;
        int age = 0;
        cin >> age;
        abs->personArray[ret].m_Age = age;

        //修改电话
        string phone;
        cout << "请输入电话:" << endl;
        cin >> phone;
        abs->personArray[ret].m_Phone = phone;

        //修改住址
        string address;
        cout << "请输入住址:" << endl;
        cin >> address;
        abs->personArray[ret].m_Address = address;
        cout << " 修改成功!" << endl;
    }
    else   //未查找到联系人
    {
        cout << " 杳无此人" << endl;
    }

    system("pause");
    system("cls");
  
}

清空联系人

清空联系人 ,这里使用了一个比较暴力的手段,就是直接将通讯录的大小改为了0(m_Size = 0)

​//封装清空函数
void cleanPerson(Addressbook * abs)
{
    abs->m_Size = 0;
    cout << "通讯录已清空" << endl;
    system("pause");
    system("cls");
  
}

整体系统实现(函数调用)

整个功能实现后,也就是功能函数封装好以后,就是在主函数里调用这些功能函数。将实参传进函数体就可以了

​
#include<iostream>
using namespace std;
#include<string>

#define MAX 1000 //通讯录联系人数最多为1000 用宏定义是为了方便维护

int main()
{
    showMenu(); //调用菜单显示函数

    //创建结构体变量
    Addressbooks abs;

    //初始化通讯录中当前人员个数
    abs.m_Size = 0;

    //搭建选择选项,这里用switch来判断多种情况选一种
    //首先定义一个输入选择的变量  
    int select = 0;
    cin >> select;

    //为了每次都能返回菜单,所以需要一个循环,只有当输入0的时候才会推出这个
    while(ture)
    {

        switch(select)
        {
            case 1:     //1、添加联系人
                addPerson(&abs); //利用地址传递,可以修饰实参
                break;
            case 2:
                showPerson(&abs)    //2、显示联系人
                break;
            case 3:    //3、删除联系人
                deletePerson(&abs)
                break;

            case 4:    //4、修改联系人
                modifyPerson(&abs)
                break;
    
            case 5:    //5、查找联系人
                findPerson(&abs)
                break;

            case 6:    //6、清空联系人
                cleanPerson(&abs)
                break;

            case 0:    //0、推出通讯录
                cout << "欢迎下次使用"<<endl;
                systrm("pause");
                return 0;
                break;

            default:
                break;
        }  
    }  

    syetrm("pause");
    return 0;

}

​

 以上就是整个通讯录管理系统的实现,主要还是指针部分还有点反应不过来,后面继续理解一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值