用编程实现简单通讯录(函数指针数组,函数回调,动态内存开辟,类等)

实现一个简单通讯录

首先主要有姓名,年龄,性别,联系方式。同时要对其进行增删改查等操作。
我们要创建一个类,来存放联系人的信息。然后再来一个枚举常量,用来准备接收switch的条件(增删改查等)。用枚举常量会增加代码的可读性。
其中包含了快速冒泡排序,函数回调,函数指针数组(转移表)等。

  • 现要求能进行以下操作:
    1. 添加联系人信息
    2. 删除指定联系人信息
    3. 查找指定联系人信息
    4. 修改指定联系人信息
    5. 显示所有联系人信息
    6. 清空所有联系人
    7. 以名字排序所有联系人

话不多说,直接开始

  • 头文件部分:
#ifndef __CONTACT_H__
#define __CONTACT_H__

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>

enum OPION
{
    EXIT,
    ADD,
    DEL,
    SEARCH,
    MODIFY,
    SHOW,
    SORT,
    EMPTY
};

enum CHOICE
{
    EXITX,
    NAME,
    AGE,
    SEX,
    NUM
};

typedef struct Peo
{
    char name[20];
    int age;
    char sex[5];
    char num[15];
}Peo;
typedef struct Contact
{
    int count;
    int capacity;
    Peo * data;
}Contact,*pContact;

void DestoryContact(pContact arr);  //结束程序前销毁释放动态内存
void is_capacait(pContact arr);  //判断增容
void InitContact(pContact arr);  //初始化联系人信息
void AddContact(pContact arr);   //增加联系人信息
void ShowContact(pContact arr);  //显示联系人信息
void DelContact(pContact arr);   //删除一个联系人
void SearchContact(pContact arr);//查询联系人信息
void ModifyContact(pContact arr);//修改联系人信息
void change(char *buf1, char *buf2, int width);//交换联系人信息
void SortContact(void* base, int sz, int width, 
                 int(*cmp)(const void *e1, const void *e2));//排序,判断是否交换联系人信息


#endif
  • 函数部分
#define _CRT_SECURE_NO_WARNINGS 1
#include "Contact.h"

void menu()
{
    printf("+---------------------+\n");
    printf("+-  根据对应选项操作 -+\n");
    printf("+- 1.添加     2.删除 -+\n");
    printf("+- 3.查询     4.修改 -+\n");
    printf("+- 5.显示     6.排序 -+\n");
    printf("+- 7.清除     0.退出 -+\n");
    printf("+---------------------+\n");
}

void InitContact(pContact arr) //初始化联系人信息
{
    arr->count = 0; //来控制联系人数组的下标
    arr->capacity = 3;//控制容量
    arr->data = (Peo *)calloc(sizeof(Peo), arr->capacity); //将所有内容置为0
}
void is_capacait(pContact arr)
{
    if(arr->count == arr->capacity)
    {
        arr->data = (Peo *)realloc(arr->data,sizeof(Peo)*(arr->capacity+2));
        arr->capacity += 2;
        printf("增容成功\n");
    }
}
void AddContact(pContact arr) //添加联系人信息
{
    //判断增容
    is_capacait(arr);
    printf("请输入姓名:\n");
    scanf("%s",arr->data[arr->count].name);
    printf("请输入年龄:\n");
    scanf("%d",&(arr->data[arr->count].age));
    printf("请输入性别:\n");
    scanf("%s",arr->data[arr->count].sex);
    printf("请输入手机号码:\n");
    scanf("%s",arr->data[arr->count].num);
    arr->count++;
}

void ShowContact(pContact arr)  //显示联系人
{
    int i = 0;
    if(arr->count == 0)
    {
        printf("通讯录无联系人信息\n");
        return;
    }
    printf("现有联系人\n");
    printf("+---------------------+\n");
    for(i=0; i<arr->count; i++)//循环打印每个联系人
    {
        printf("%s,%d,%s,%s\n",arr->data[i].name,arr->data[i].age,arr->data[i].sex,
                            arr->data[i].num);
    }
    printf("+---------------------+\n");
}

void DelContact(pContact arr)//删除指定联系人信息
{
    int i = 0;
    int j = 0;
    char buf[20];
    if(arr->count == 0)
    {
        printf("什么都没有,你删个鬼\n");
        return;
    }
    printf("请输入你想删除的人的姓名:\n");
    scanf("%s",buf);
    for(i=0; i<arr->count; i++)
    {
        j = arr->count;
        if(strcmp(arr->data[i].name,buf) == 0)
        //遍历找到对应联系人信息
        {
            j = i;
            while(j<(arr->count))
            //用循环将这个联系人先移动到最后一个位置
            {
                strcpy(arr->data[j].name,arr->data[j+1].name);
                arr->data[j].age = arr->data[j+1].age;
                strcpy(arr->data[j].sex,arr->data[j+1].sex);
                strcpy(arr->data[j].num,arr->data[j+1].num);
                j++;
            }
            //将该联系人移动到最后一个位置后,将其初始化
            memset(arr->data[j].name,0,sizeof(arr->data[j].name));
            arr->data[j].age = 0;
            memset(arr->data[j].sex,0,sizeof(arr->data[j].sex));
            memset(arr->data[j].num,0,sizeof(arr->data[j].num));
            arr->count--; //将其联系人下标删除。
            printf("删除成功\n");
            return;
            //删除成功。直接返回。否则有可能会执行下面的if语句
        }
    }
    if(j == arr->count)
    {
        printf("删除失败,请检查名字是否正确\n");
    }
}

void SearchContact(pContact arr)//查询联系人信息
{
    int i = 0;
    char buff[20];
    int j = 0;
    int x = 0;
    if(arr->count == 0)
    {
        printf("什么都没有,没有联系人可查\n");
        return;
    }
    do
    {
        printf("姓名查询请按1,年龄查询按2,性别查询按3,电话查询按4,退出查询按0\n");
        scanf("%d",&i);
        switch(i)
//遍历找到每个信息对应的联系人,并将其所有符合条件的联系人打印
        {
        case NAME://找到名字对应的打印
            printf("请输入要查询的姓名:");
            scanf("%s",buff);
            for(x=0; x<arr->count; x++)
            {
                if(strcmp(arr->data[x].name,buff) == 0)
                    printf("%s,%d,%s,%s\n",arr->data[x].name,arr->data[x].age,
                                            arr->data[x].sex,arr->data[x].num);
            }
            break;
        case AGE://找到年龄对应的打印
            printf("请输入要查询的年龄:");
            scanf("%d",&j);
            for(x=0; x<arr->count; x++)
            {
                if(j == arr->data[x].age)
                    printf("%s,%d,%s,%s\n",arr->data[x].name,arr->data[x].age,
                                            arr->data[x].sex,arr->data[x].num);
            }
            break;
        case SEX://找到性别对应的打印
            printf("请输入要查询的性别:");
            scanf("%s",buff);
            for(x=0; x<arr->count; x++)
            {
                if(strcmp(arr->data[x].sex,buff) == 0)
                    printf("%s,%d,%s,%s\n",arr->data[x].name,arr->data[x].age,
                                            arr->data[x].sex,arr->data[x].num);
            }
            break;
        case NUM://找到电话号码对应的打印
            printf("请输入要查询的电话号码:");
            scanf("%s",buff);
            for(x=0; x<arr->count; x++)
            {
                if(strcmp(arr->data[x].num,buff) == 0)
                    printf("%s,%d,%s,%s\n",arr->data[x].name,arr->data[x].age,
                                            arr->data[x].sex,arr->data[x].num);
            }
            break;
        case EXITX:
            printf("已退出查询\n");
            return;
        }
    }while(i);
}

void ModifyContact(pContact arr)  //修改联系人信息
{
    char buf1[20];
    int i = 0;
    int j = 0;
    if(arr->count == 0)
    {
        printf("什么都没有,没有联系人可改\n");
        return;
    }
    printf("请输入你想修改的人的名字\n");
    scanf("%s",buf1);
    for(i=0; i<arr->count; i++)
    {
        if(strcmp(arr->data[i].name,buf1) == 0)
        //找到对应的联系人,重新填写联系人信息
        {
            printf("请输入新的姓名:\n");
            scanf("%s",arr->data[i].name);
            printf("请输入新的年龄:\n");
            scanf("%d",&(arr->data[i].age));
            printf("请输入新的性别:\n");
            scanf("%s",arr->data[i].sex);
            printf("请输入新的手机号码:\n");
            scanf("%s",arr->data[i].num);
            printf("修改成功\n");
            printf("%s,%d,%s,%s\n",arr->data[i].name,arr->data[i].age,
                                    arr->data[i].sex,arr->data[i].num);
            j++;
        }
    }
    if(j == 0)
    {
        printf("该联系人不存在\n");
    }
}
void SortContact(void* base, int sz, int width, 
                 int(*cmp)(const void *e1, const void *e2))
                 //快速排序适用于各类排序
{
    int i = 0;
    int j = 0;
    assert(base && cmp);
    for(i=0; i<sz-1; i++)
    {
        for(j=0; j<sz-i-1; j++)
        {
            if(cmp((char*)base+width*j, (char*)base+width*(j+1))>0)
            {
                change((char*)base+width*j,(char*)base+width*(j+1),width);
            }
        }
    }
}


//定义4个比较大小的函数,为冒泡排序做准备
int name_cmp(const void *e1, const void *e2)
{
    assert(e1&&e2);
    return strcmp(((Peo *)e1)->name,((Peo *)e2)->name);
}
int age_cmp(const void *e1, const void *e2)
{
    return ((Peo *)e1)->age-((Peo *)e2)->age;
}
int sex_cmp(const void *e1, const void *e2)
{
    assert(e1&&e2);
    return strcmp(((Peo *)e1)->sex,((Peo *)e2)->sex);
}
int num_cmp(const void *e1, const void *e2)
{
    assert(e1&&e2);
    return strcmp(((Peo *)e1)->num,((Peo *)e2)->num);
}

//交换联系人信息函数
void change(char *buf1, char *buf2, int width)
{
    int i = 0;
    assert(buf1 && buf2);
    for(i=0; i<width; i++)
    {
        char tmp = *buf1;
        *buf1 = *buf2;
        *buf2 = tmp;
        buf1++;
        buf2++;
    }
}
//定义一个函数指针
int (*pf)(const void *e1, const void *e2) = NULL;

//创建一个类,
struct operation
{
    int (*p)(const void *e1, const void *e2);
}opers[] = {NULL, name_cmp, age_cmp, sex_cmp, num_cmp};
//创建一个类数组,数组里面放的是比较大小的函数的地址。

void DestoryContact(pContact arr)  //结束程序前销毁释放动态内存
{
    free(arr->data);
    arr->count = 0;
    arr->capacity = 0;
    arr->data = NULL;
    printf("销毁成功\n");
}
  • 主函数main
#define _CRT_SECURE_NO_WARNINGS 1
#include "Contact.h"

int main()
{
    int input = 0;
    Contact con;
    int m = 0;
    int sz = sizeof(Peo);
    InitContact(&con);//初始化联系人信息
    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:
            do
            {
                printf("姓名排序请按1,年龄排序按2,性别排序请按3,电话排序请按4,退出排序请按0\n");
                scanf("%d",&m);
                if(m == 0) break;//没有联系人信息直接返回
                if(m>0 && m<=4)//判断一下,防止出先未知函数指针。
                    SortContact(con.data, con.count, sizeof(con.data[0]), opers[m].p);
                            //万能冒泡排序传数组地址,元素个数,元素大小,已经比较元素函数的指针
                ShowContact(&con);
            }while(m);
            break;
        case EMPTY:
            DestoryContact(&con);//初始化联系人信息
            printf("清除成功,联系人已为空\n");
            break;
        case EXIT:
            DestoryContact(&con);
            return 0;//退出,直接返回main函数
        default:
            printf("输入错误\n");
            //getchar();
            break;
        }
    }while(input);
    return 0;
}
  • 下面是运行结果图
    1. 添加联系人信息
      这里写图片描述
    2. 删除指定联系人信息
      这里写图片描述
    3. 查找指定联系人信息
      这里写图片描述
    4. 修改指定联系人信息
      这里写图片描述
    5. 显示所有联系人信息
      这里写图片描述
    6. 清空所有联系人
      这里写图片描述
    7. 排序所有联系人
      这里写图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值