用结构体实现通讯录(动态实现)

🐶博主主页:@ᰔᩚ. 一怀明月ꦿ 

❤️‍🔥专栏系列:线性代数C初学者入门训练题解CC的使用文章「初学」C++

🔥座右铭:“不要等到什么都没有了,才下定决心去做”

🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀

目录

🌸通讯录的需求

🌸通讯录的功能

🐰 通讯录的原码 

🌸主函数

🌸头文件

🌸函数实现文件


🌸通讯录的需求

1.人员的姓名
2.人员的年龄
3.人员的性别
4.人员的电话号码
5.人员的地址
实现方法:通讯录初始设置data_max(我这里设置3)个人的空间,开辟data_max个人的空间,动态创建(使用malloc)data_max个人的空间。我们设置两个结构体,一个保存通讯录的需求,一个保存结构体结构体动态创建的空间,通讯录的人数和通讯录最大容量。

🌸通讯录的功能

相较于静态的通讯录,我们改变了初始化通讯录,增加联系人的功能,添加了判断通讯录空间是否足够的函数,通讯录清空的功能。所以我只大家介绍改变的和新增的功能及函数

初始化通讯录:

//动态版本的初始化
void InitContact(Contact* pc)
{
    pc->data=(PeoInfo*)malloc(sizeof(PeoInfo)*data_max);//最开始给通讯录开辟data_max个空间
    if(pc->data==NULL)
    {
        printf("开辟空间失败:%s\n",strerror(errno));
        return ;
    }
    pc->sz=0;
    pc->capacity=data_max;//容量最大空间当然也是data_max
}

初始化时,最开始给通讯录动态开辟data_max个空间,如果开辟空间失败时,打印出开辟空间失败的原因,开辟成功,将联系人的个数置为0,通讯录的空间置为data_max。

判断通讯录空间是否足够:

int CheckCapacity(Contact* pc)
{
    if(pc->sz==pc->capacity)
    {
        PeoInfo* ptr=(PeoInfo*)realloc(pc->data,sizeof(pc->capacity)*2);
        if(ptr==NULL)
        {
            printf("增容失败:%s\n",strerror(errno));
            return 0;
        }
        else
        {
            pc->data=ptr;
            pc->capacity=pc->capacity*2;
            printf("增容成功,容量为%d\n",pc->capacity);
            return 1;
        }
    }
    return 1;
}

如果联系人的个数等于通讯录的最大空间,则需要给通讯录扩容,这里采用的是扩容为原来空间两倍的方式扩容。如果扩容失败,打印扩容失败的原因。如果扩容成功,将扩容空间的首地址保存下来,将通讯录的最大容量更新为原来的两倍。还有,如果扩容成功或则不需要就返回1,扩容失败就返回0。

增加联系人:

void AddContact(Contact* pc)
{
    if(CheckCapacity(pc)==0)
    {
        printf("扩容失败\n");
        return;
    }
    else
    {
        printf("请输入名字\n");
        scanf("%s",pc->data[pc->sz].name);
        printf("请输入年龄\n");
        scanf("%d",&(pc->data[pc->sz].age));
        printf("请输入性别\n");
        scanf("%s",pc->data[pc->sz].sex);
        printf("请输入电话号码\n");
        scanf("%s",pc->data[pc->sz].tele);
        printf("请输入地址\n");
        scanf("%s",pc->data[pc->sz].addr);
        pc->sz++;
        printf("添加成功\n");
    }
}

如果通过判断通讯录空间是否足够的函数得到返回值为1,我们就可以添加联系人的信息,如果返回值为0,就结束该进程。

通讯录清空:

void DestroyContact(Contact* pc)
{
    free(pc->data);
    pc->data=NULL;
    pc->sz=0;
    pc->capacity=0;
    printf("清空通讯录...\n");
}

因为我们是动态开辟空间去创建的通讯录,所以需要手动去释放这些动态开辟的空间,因为系统在程序结束之前,是不会自动释放在堆使用的空间。这样做的目的也刚好满足清空通讯录的要求。

🐰 通讯录的原码 

🌸主函数

#include"test.h"
void menu(void)
{
    printf("===========================\n");
    printf("        1.添加,2.删除       \n");
    printf("        3.查找,4.改动       \n");
    printf("        5.展示,6.排序       \n");
    printf("        7.清空,0.退出             \n");
    printf("===========================\n");
}
enum Option
{
    EXIT,
    ADD,
    DEL,
    SEARCH,
    MODIFY,
    SHOW,
    SORT,
    DESTROY,
};
int main()
{
    Contact con;
    InitContact(&con);
    int input=0;
    int op=0;
    do
    {
        menu();
        printf("请选择\n");
        scanf("%d",&input);
        switch(input)
        {
            case ADD:
                AddContact(&con);
                break;
            case DEL:
                DelContact(&con);
                break;
            case SEARCH:
                SearchContact(&con);
                break;
            case MODIFY:
                ModifyContact(&con);
                break;
            case SHOW:
                ShowContact(&con);
                break;
            case SORT:
                printf("请选择排序方法\n");
                printf("=========================\n");
                printf("1.按名字排序     2.按年龄排序\n");
                printf("=========================\n");
                scanf("%d",&op);
                SortContact(&con,op);
            case DESTROY:
                DestroyContact(&con);
                break;
            case EXIT:
                DestroyContact(&con);
                printf("退出通讯录\n");
                break;
            default:
                printf("输入错误\n");
                break;
        }
    }while(input);
}

🌸头文件

#ifndef test_h
#define test_h
#include <stdio.h>
#endif /* test_h */

#include<string.h>
#include<stdlib.h>
#include<errno.h>

#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30


#define data_max 3
typedef struct PeoInfo
{
    char name[MAX_NAME];
    int age;
    char sex[MAX_SEX];
    char tele[MAX_TELE];
    char addr[MAX_ADDR];
}PeoInfo;

//typedef struct Contact
//{
//    PeoInfo data[MAX];//存放数据
//    int sz;//有效信息的个数
//}Contact;



//动态的版本
//1.默认能够存储3个人的信息
//2.不够扩容为原来空间的两倍

typedef struct Contact
{
    PeoInfo *data;//存放数据
    int sz;//有效信息的个数
    int capacity;//通讯录当前最大容量
}Contact;




//初始化
void InitContact(Contact* pc);
//增加指定联系人
void AddContact(Contact* pc);
//展示联系人的信息
void ShowContact(Contact* pc);
//删除指定人信息
void DelContact(Contact* pc);
//查找指定人的信息
void SearchContact(Contact* pc);
//改变指定人信息
void ModifyContact(Contact* pc);
//给通讯录的人信息排序
void SortContact(Contact* pc,int op);
//清空通讯录
void DestroyContact(Contact* pc);

🌸函数实现文件

#include "test.h"
//静态版本的初始化
//void InitContact(Contact* pc)
//{
//    pc->sz=0;
//    memset(pc->data,0,sizeof(pc->data));
//}
//动态版本的初始化
void InitContact(Contact* pc)
{
    pc->data=(PeoInfo*)malloc(sizeof(PeoInfo)*data_max);//最开始给通讯录开辟data_max个空间
    if(pc->data==NULL)
    {
        printf("开辟空间失败:%s\n",strerror(errno));
        return ;
    }
    pc->sz=0;
    pc->capacity=data_max;//容量最大空间当然也是data_max
}
//静态增加人员的信息
//void AddContact(Contact* pc)
//{
//    if(pc->sz==MAX)
//    {
//        printf("通讯录已满,无法增加\n");
//    }
//    else
//    {
//        printf("请输入名字\n");
//        scanf("%s",pc->data[pc->sz].name);
//        printf("请输入年龄\n");
//        scanf("%d",&(pc->data[pc->sz].age));
//        printf("请输入性别\n");
//        scanf("%s",pc->data[pc->sz].sex);
//        printf("请输入电话号码\n");
//        scanf("%s",pc->data[pc->sz].tele);
//        printf("请输入地址\n");
//        scanf("%s",pc->data[pc->sz].addr);
//    }
//    pc->sz++;
//    printf("添加成功\n");
//}

//检查是否需要扩容
int CheckCapacity(Contact* pc)
{
    if(pc->sz==pc->capacity)
    {
        PeoInfo* ptr=(PeoInfo*)realloc(pc->data,sizeof(pc->capacity)*2);
        if(ptr==NULL)
        {
            printf("增容失败:%s\n",strerror(errno));
            return 0;
        }
        else
        {
            pc->data=ptr;
            pc->capacity=pc->capacity*2;
            printf("增容成功,容量为%d\n",pc->capacity);
            return 1;
        }
    }
    return 1;
}
//动态增加人员信息
void AddContact(Contact* pc)
{
    if(CheckCapacity(pc)==0)
    {
        printf("扩容失败\n");
        return;
    }
    else
    {
        printf("请输入名字\n");
        scanf("%s",pc->data[pc->sz].name);
        printf("请输入年龄\n");
        scanf("%d",&(pc->data[pc->sz].age));
        printf("请输入性别\n");
        scanf("%s",pc->data[pc->sz].sex);
        printf("请输入电话号码\n");
        scanf("%s",pc->data[pc->sz].tele);
        printf("请输入地址\n");
        scanf("%s",pc->data[pc->sz].addr);
        pc->sz++;
        printf("添加成功\n");
    }
}

void ShowContact(Contact* pc)
{
    printf("%-10s %-4s %-5s %-12s %-30s\n","性别","年龄","性别","电话号码","地址");
    for(int i=0;i<pc->sz;i++)
    {
        printf("%-10s %-4d %-5s %-12s %-30s\n",pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].tele,pc->data[i].addr);
    }
}
int Find_name(Contact* pc,char name[])
{
    int i;
    int pos=-1;
    for( i=0;i<pc->sz;i++)
    {
        if(strcmp(name,pc->data[i].name)==0)
        {
            pos=i;
            break;
        }
    }
    return pos;
}
void DelContact(Contact* pc)
{
    if(pc->sz==0)
    {
        printf("通讯录为空,无法删除\n");
    }
    //删除
    //1.找到删除人的位置
    char name[MAX_NAME];
    int pos=-1;
    int i;
    printf("输入删除人的名字;>\n");
    scanf("%s",name);
    pos=Find_name(pc,name);
    if(pos==-1)
    {
        printf("要删的人不存在\n");
    }
    else{
        for(i=pos;i<pc->sz-1;i++)
        {
            pc->data[i]=pc->data[i+1];
        }
        pc->sz--;
        printf("删除成功\n");
    }
}
void SearchContact(Contact* pc)
{
    char name[MAX_NAME];
    printf("输入查找人的名字;>\n");
    scanf("%s",name);
    int pos=-1;
    pos=Find_name(pc, name);
    if(pos==-1)
    {
        printf("查找的人不存在\n");
    }
    else
    {
        printf("%-10s %-4s %-5s %-12s %-30s\n","性别","年龄","性别","电话号码","地址");
        printf("%-10s %-4d %-5s %-12s %-30s\n",pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].tele,pc->data[pos].addr);
    }
}
void ModifyContact(Contact* pc)
{
    char name[MAX_NAME];
    printf("输入修改人的名字;>\n");
    scanf("%s",name);
    int pos=-1;
    pos=Find_name(pc, name);
    if(pos==-1)
    {
        printf("修改人信息不存在\n");
    }
    else
    {
        printf("请输入名字\n");
        scanf("%s",pc->data[pos].name);
        printf("请输入年龄\n");
        scanf("%d",&(pc->data[pos].age));
        printf("请输入性别\n");
        scanf("%s",pc->data[pos].sex);
        printf("请输入电话号码\n");
        scanf("%s",pc->data[pos].tele);
        printf("请输入地址\n");
        scanf("%s",pc->data[pos].addr);
        printf("修改成功\n");
    }
}
int cmp_by_name(const void* e1,const void* e2)
{
    return strcmp(((PeoInfo*)e1)->name,((PeoInfo*)e2)->name);
}
int cmp_by_gae(const void* e1,const void* e2)
{
    return ((PeoInfo*)e1)->age-((PeoInfo*)e2)->age;
}
void SortContact(Contact* pc,int op)
{
    if(op==1)
    {
        qsort(pc->data,pc->sz,sizeof(PeoInfo),cmp_by_name);
        printf("排序成功\n");
    }
    if(op==2)
    {
        qsort(pc->data,pc->sz,sizeof(PeoInfo),cmp_by_gae);
        printf("排序成功\n");
    }
}
void DestroyContact(Contact* pc)
{
    free(pc->data);
    pc->data=NULL;
    pc->sz=0;
    pc->capacity=0;
    printf("清空通讯录...\n");
}

🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸  

  • 31
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 51
    评论
评论 51
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值