C语言实现通讯录(简易版)

一、前言

本文将会用C语言实现通讯录系统。

此通讯录的联系人的信息由---姓名---性别---年龄---联系方式---家庭住址---这五个部分组成。

通讯录的功能包含以下6点

  1. 增加联系人

  1. 删除目标联系人

  1. 查找目标联系人

  1. 修改目标联系人的信息

  1. 排序通讯录的联系人

  1. 打印通讯录联系人的信息

二、通讯录如何实现

  1. 菜单的创建和选择

为通讯录打造一个菜单,以便用户了解通讯录的相关功能。

首先需要建立一个菜单,便于用户了解此通讯录

代码如下:

使用printf引用头文件

#include

void menu()
{
    printf("*****************************************\n");
    printf("*******    1.Add     2.Erase       ******\n");
    printf("*******    3.Search   4.Amend      ******\n");
    printf("*******    5.Sort     6.Print      ******\n");
    printf("***********     0.Exit     **************\n");
}

运行效果如下:

C语言实现通讯录(简易版)_第1张图片

根据菜单里的选项进行相关功能的实现

采用枚举类型的结构体,成员变量的大小是从0开始,依次递增

enum option
{
    EXIT,
    ADD,
    ERASE,
    SEARCH,
    AMEND,
    SORT,
    PRINT
};

EXIT代表0依次递增

写代码实现菜单功能使用do while语句进行最少一次的循环

int main()
{
    int input = 0;
    do
    {
        menu();
        printf("请选择:>");
        scanf("%d", &input);
        switch (input)
        {
        case ADD:
            break;
        case ERASE:
            break;
        case SEARCH:
            break;
        case AMEND:
            break;
        case SORT:
            break;
        case PRINT:
            break;
        case EXIT:
            printf("退出通讯录\n");
            break;
        default:
            printf("选择错误,重新输入\n");
            break;
        }
    } while(input);
}
  1. 联系人如何创建

一个人联系人由---姓名--性别--年龄--联系方式--家庭住址,这五个部分组成。

所以用结构体来组成联系人信息。

typedef struct peoinfo    //typedef结构体定义一个新的名字
{
    char name[NAME_MAX];
    char set[SET_MAX];
    int age;
    char tele[TELE_MAX];
    char addr[ADDR_MAX];
}peoinfo;

//静态版本
//创建一个结构体变量包含     data数组&&sz
typedef struct contack
{
    peoinfo data[MAX];//1000个结构体为peoinfo中存放的信息
    int sz;//记录当前通讯录中有效信息的个数
}contack;

以上是两个结构体

第一个结构体组成联系人的信息

第二个结构体以data命名peoinfo这个结构体 data[MAX]为表示有MAX个数组,记录此通讯录当前有效信息的个数。

对MAX以及第一个结构体的元素数组进行宏定义以便更好的维护

如下代码:

#define NAME_MAX 20
#define SET_MAX 10
#define TELE_MAX 20
#define ADDR_MAX 10
#define MAX 1000
  1. 通讯录功能实现
(1) 通讯录的创建和初始化

首先需要创建通讯录在将其初始化

初始化函数使用memset这个库函数

memset的作用是将某一块内存中的内容全部设置为指定的值

使用memset函数引用头文件

#include

    contack con;//创建通讯录

    initcontack(&con);//初始化通讯录
//初始化函数实现如下
void initcontack(contack* p)
{
    p->sz = 0;//sz为当前通讯录中有效信息的个数
    memset(p->data, 0, sizeof(p->data));//sizeof(p->data)计算结构体data的内存大小
    //p->data 数组名代表首元素地址
}
(2) 实现增加联系人的功能

创建一个函数实现这个功能

Addcontack(&con);

//静态版本增加联系人
void  Addcontack(contack* p)
{
    //增加需要考虑的因素 ->  人员满了无法增加
    if (p->sz == MAX)
    {
        printf("通讯录已满,无法进行增加\n");
        return;
    }
    printf("请输入增加联系人的姓名\n");
    scanf("%s", p->data[p->sz].name);//[p->sz]data数组的下标
    printf("请输入增加联系人的性别\n");
    scanf("%s", p->data[p->sz].set);
    printf("请输入增加联系人的年龄\n");
    scanf("%d", &(p->data[p->sz].age));//age为int 变量要取地址
    printf("请输入增加联系人的电话\n");
    scanf("%s", p->data[p->sz].tele);
    printf("请输入增加联系人的地址 \n");
    scanf("%s", p->data[p->sz].addr);

    //此时结构体内容全部添加所以tada数组下标自增
    p->sz++;
    printf("添加成功\n");
}

效果如下:

C语言实现通讯录(简易版)_第2张图片

(3) 实现打印功能

上面进行了增加功能我们打印出来看看是否保存了该联系人的信息

void Printcontack(const contack* p)
{
    int i = 0;
    //打印标题
    printf("%-20s\t %-5s\t %-5s\t %-15s\t %-20s\n", "姓名", "性别", "年龄", "电话", "地址");
    for (i = 0; i < p->sz; i++)
    {
        printf("%-20s\t %-5s\t %-5d\t %-15s\t %-20s\n",
            p->data[i].name,
            p->data[i].set,
            p->data[i].age,
            p->data[i].tele,
            p->data[i].addr);
    }
}

%-20\t 为左对齐20个tab单位

(4)实现查找联系人的功能

查找目标联系人得先查找是否有目标联系人,在进行(修改和删除)功能得实现也能用上

所以我们在创建一个查找联系人得函数然后在进行查找功能的实现

代码如下:

//查找用名字联系人代码 没有目标联系人返回-1, 有则返回目标联系人得下标
int Findbyname(contack* p, char name[])
{
    int i = 0;
    for (i = 0; i < p->sz; i++)
    {
        if (strcmp(p->data[i].name, name) == 0)
        {
            return i;
        }
    }
    return -1;
}

void Searchcontack(const  contack* p)
{
    char name[NAME_MAX] = { 0 };
    printf("请输入要查找联系人的姓名\n");
    scanf("%s", name);
    int ret = Findbyname(p, name);
    if (ret == -1)
    {
        printf("要查找的联系人不存在\n");
        return;
    }
    else
    {
        printf("%-20s\t %-5s\t %-5s\t %-15s\t %-20s\n", "姓名", "性别", "年龄", "电话", "地址");
        //打印查找到联系人的数据
        printf("%-20s\t %-5s\t %-5d\t %-15s\t %-20s\n",
                p->data[ret].name,
                p->data[ret].set,
                p->data[ret].age,
                p->data[ret].tele,
                p->data[ret].addr);
    }
}

(5)实现修改联系人的功能

修改一个人的信息得先查找这个人是否在本通讯录中所以应用我们之前创建得修改函数即可

void Amendcontack(contack* p)
{
    //修改联系人的姓名
    //调用修改联系人的数据进行修改
    char name[NAME_MAX] = { 0 };
    printf("请输入要修改 联系人的姓名\n");
    scanf("%s", name);
    int ret = Findbyname(p, name);
    if (ret == -1)
    {
        printf("要修改的联系人不存在\n");
        return;
    }
    else
    {
        printf("请输入联系人的姓名\n");
        scanf("%s", p->data[ret].name);//[p->sz]data数组的下标
        printf("请输入联系人的性别\n");
        scanf("%s", p->data[ret].set);
        printf("请输入联系人的年龄\n");
        scanf("%d", &(p->data[ret].age));//age为int 变量要取地址
        printf("请输入联系人的电话\n");
        scanf("%s", p->data[ret].tele);
        printf("请输入联系人的地址 \n");
        scanf("%s", p->data[ret].addr);
        printf("修改成功\n");
    }
}
C语言实现通讯录(简易版)_第3张图片

查看是否修改成功

(6)实现删除联系人得功能

删除用到查找联系人是否存在的函数在写查找功能的时候已经写了这里我们用就行了

首先我们先利用查找联系人是否存在的功能,查找目标联系人的下标

查找到我们需要寻找删除联系人的坐标,然后对他进行删除(覆盖),将后面的元素覆盖到前面要删除的元素即可,依次类推将后面的元素全部往前覆盖一个for循环即可,注意别越界访问

void Erasecontack(contack* p)
{
    char name[NAME_MAX] = { 0 };
    //删除联系人需要的考虑的因素
    if (p->sz == 0)
    {
        printf("通讯录为空,无法进行删除\n");
        return;
    }
    //没有空
    printf("请输入要删除联系人的姓名\n");
    scanf("%s", name);
    //查找有无此联系人
    int ret = Findbyname(p, name);
    if (ret == -1)
    {
        printf("要删除的联系人不存在\n");
        return;
    }
    //存在的情况下
    int i = 0;
    for (i = ret; i < p->sz - 1; i++)
    {
        p->data[i] = p->data[i + 1];
    }
    p->sz--;
}
(7)实现排序联系人的功能

使用qsort库函数进行快速排序

使用qsort引用头文件

#include

这里我们采用的是用姓名的字符串进行排序

排序成功在调用打印通讯录的函数将调用后的通讯录显示出来

int name_qsort(const void* e1, const void* e2)
{
    return strcmp(((peoinfo*)e1)->name, ((peoinfo*)e2)->name);
}

void Sortcontack(const contack* p)
{
    //根据姓名首字母进行排序联系人
    if (p->sz == 0)
    {
        printf("通讯录为空, 无法排序\n");
    }
    else
    {
        //使用qsort进行快速排序
        qsort(p, p->sz, sizeof(peoinfo), name_qsort);
        Printcontack(p);//调用打印函数
        printf("排序成功\n");
    }
}
C语言实现通讯录(简易版)_第4张图片

三、通讯录完成(全部代码)

此通讯录分为三个文件内容组成

test.c 和 contack.c 得引用"contack.h"文件

  1. test.c文件

此文件为通讯录的运行逻辑逻辑

#define _CRT_SECURE_NO_WARNINGS 1
#include "contack.h"

void menu()
{
    printf("*****************************************\n");
    printf("*******    1.Add      2.Erase      ******\n");
    printf("*******    3.Search   4.Amend      ******\n");
    printf("*******    5.Sort     6.Print      ******\n");
    printf("***********     0.Exit     **************\n");
}

//使用枚举类型的结构体    成员变量默认值是从0开始递增
enum option
{
    EXIT,
    ADD,
    ERASE,
    SEARCH,
    AMEND,
    SORT,
    PRINT
};

int main()
{
    int input = 0;

    //创建通讯录
    contack con;

    //初始化通讯录
    //给data申请一块连续的空间在堆区上
    //sz=0;
    //capacity  初始化当前最大的容量
    initcontack(&con);

    do
    {
        menu();
        printf("请选择:>");
        scanf("%d", &input);
        switch (input)
        {
        case ADD:
            Addcontack(&con);
            break;
        case ERASE:
            Erasecontack(&con);
            break;
        case SEARCH:
            Searchcontack(&con);
            break;
        case AMEND:
            Amendcontack(&con);
            break;
        case SORT:
            Sortcontack(&con);
            break;
        case PRINT:
            Printcontack(&con);
            break;
        case EXIT:
            //Destorycontack(&con);
            printf("退出通讯录\n");
            break;
        default:
            printf("选择错误,重新输入\n");
            break;
        }
    } while(input);
}
  1. contack.h文件

包含引用的头文件---宏定义---函数声明

#pragma once
#include 
#include 
#include 

//定义宏  
#define NAME_MAX 20
#define SET_MAX 10
#define TELE_MAX 20
#define ADDR_MAX 10
#define MAX 1000
#define DEFAULT_SZ 3
#define INC_SZ 2
//一个人的通讯录需要的内容变量名- peoinfo
//typedef   结构体定义一个新的名字
typedef struct peoinfo
{
    char name[NAME_MAX];
    char set[SET_MAX];
    int age;
    char tele[TELE_MAX];
    char addr[ADDR_MAX];
}peoinfo;

//静态版本
//创建一个结构体变量包含     data数组&&sz
typedef struct contack
{
    peoinfo data[MAX];//1000个结构体为peoinfo中存放的信息
    int sz;//记录当前通讯录中有效信息的个数
}contack;

//动态版本
//typedef struct contack
//{
//    peoinfo* data;//指向动态申请的空间, 用来存放联系人的信息
//    int sz;//记录当前通讯录有效个数
//    int capacity;//记录当前通讯录的最大容量
//}contack;

//初始化通讯录
void initcontack(contack*p);//传址 用指针接收-- contack为结构体指针p的类型

//增加联系人
void  Addcontack(contack*p);

//打印通讯录
void Printcontack(const contack*p);

//删除联系人
void Erasecontack(contack*p);

//查找联系人
void Searchcontack(const  contack* p);

//修改联系人
void Amendcontack(contack* p);

//排序联系人
void Sortcontack(contack* p);

//销毁通讯录
//void Destorycontack(contack* p);

3.contack.c文件

函数逻辑的实现

#define _CRT_SECURE_NO_WARNINGS 1
#include "contack.h"

//静态版本初始化
void initcontack(contack* p)
{
    p->sz = 0;//sz为当前通讯录中有效信息的个数
    memset(p->data, 0, sizeof(p->data));//sizeof(p->data)计算结构体data的内存大小
    //p->data 数组名代表首元素地址
    //memset的作用是将某一块内存中的内容全部设置为指定的值
}

动态版本初始化
//void initcontack(contack* p)
//{
//    p->data = (peoinfo*)malloc(DEFAULT_SZ * sizeof(peoinfo));
//    if (p->data == NULL)
//    {
//        perror("initcontack");
//        return;
//    }
//    p->sz = 0;//初始化为0
//    p->capacity = DEFAULT_SZ;
//}

//静态版本增加联系人
void  Addcontack(contack* p)
{
    //增加需要考虑的因素 ->  人员满了无法增加
    if (p->sz == MAX)
    {
        printf("通讯录已满,无法进行增加\n");
        return;
    }
    printf("请输入增加联系人的姓名\n");
    scanf("%s", p->data[p->sz].name);//[p->sz]data数组的下标
    printf("请输入增加联系人的性别\n");
    scanf("%s", p->data[p->sz].set);
    printf("请输入增加联系人的年龄\n");
    scanf("%d", &(p->data[p->sz].age));//age为int 变量要取地址
    printf("请输入增加联系人的电话\n");
    scanf("%s", p->data[p->sz].tele);
    printf("请输入增加联系人的地址 \n");
    scanf("%s", p->data[p->sz].addr);

    //此时结构体内容全部添加所以tada数组下标自增
    p->sz++;
    printf("添加成功\n");
}

//动态版本增加联系人
//void  Addcontack(contack* p)
//{
//    //增加需要考虑的因素 ->  人员满了无法增加
//    if (p->sz == p->capacity)
//    {
//        peoinfo* ptr = (peoinfo*)realloc(p->data, (p->capacity + INC_SZ) * sizeof(peoinfo));
//        if (ptr != NULL)
//        {
//            p->data = ptr;
//            p->capacity += INC_SZ;
//            printf("增容成功\n");
//        }
//        else
//        {
//            perror("Addcontack");
//            printf("增加联系人失败\n");
//            return;
//        }
//    }
//    printf("请输入增加联系人的姓名\n");
//    scanf("%s", p->data[p->sz].name);//[p->sz]data数组的下标
//    printf("请输入增加联系人的性别\n");
//    scanf("%s", p->data[p->sz].set);
//    printf("请输入增加联系人的年龄\n");
//    scanf("%d", &(p->data[p->sz].age));//age为int 变量要取地址
//    printf("请输入增加联系人的电话\n");
//    scanf("%s", p->data[p->sz].tele);
//    printf("请输入增加联系人的地址 \n");
//    scanf("%s", p->data[p->sz].addr);
//
//    p->sz++;
//    printf("添加成功\n");
//}

//void Destorycontack(contack* p)
//{
//    free(p->data);
//    p->data = NULL;
//    p->sz = 0;
//    p->capacity = 0;
//}

void Printcontack(const contack* p)
{
    int i = 0;
    //打印标题
    printf("%-20s\t %-5s\t %-5s\t %-15s\t %-20s\n", "姓名", "性别", "年龄", "电话", "地址");
    for (i = 0; i < p->sz; i++)
    {
        printf("%-20s\t %-5s\t %-5d\t %-15s\t %-20s\n",
            p->data[i].name,
            p->data[i].set,
            p->data[i].age,
            p->data[i].tele,
            p->data[i].addr);
    }
}

int Findbyname(contack* p, char name[])
{
    int i = 0;
    for (i = 0; i < p->sz; i++)
    {
        if (strcmp(p->data[i].name, name) == 0)
        {
            return i;
        }
    }
    return -1;
}

void Erasecontack(contack* p)
{
    char name[NAME_MAX] = { 0 };
    //删除联系人需要的考虑的因素
    if (p->sz == 0)
    {
        printf("通讯录为空,无法进行删除\n");
        return;
    }
    //没有空
    printf("请输入要删除联系人的姓名\n");
    scanf("%s", name);
    //查找有无此联系人
    int ret = Findbyname(p, name);
    if (ret == -1)
    {
        printf("要删除的联系人不存在\n");
        return;
    }
    //存在的情况下
    int i = 0;
    for (i = ret; i < p->sz - 1; i++)
    {
        p->data[i] = p->data[i + 1];
    }
    p->sz--;
}

void Searchcontack(const  contack* p)
{
    char name[NAME_MAX] = { 0 };
    printf("请输入要查找联系人的姓名\n");
    scanf("%s", name);
    int ret = Findbyname(p, name);
    if (ret == -1)
    {
        printf("要查找的联系人不存在\n");
        return;
    }
    else
    {
        printf("%-20s\t %-5s\t %-5s\t %-15s\t %-20s\n", "姓名", "性别", "年龄", "电话", "地址");
        //打印查找到联系人的数据
        printf("%-20s\t %-5s\t %-5d\t %-15s\t %-20s\n",
                p->data[ret].name,
                p->data[ret].set,
                p->data[ret].age,
                p->data[ret].tele,
                p->data[ret].addr);
    }
}

void Amendcontack(contack* p)
{
    //修改联系人的姓名
    //调用修改联系人的数据进行修改
    char name[NAME_MAX] = { 0 };
    printf("请输入要修改 联系人的姓名\n");
    scanf("%s", name);
    int ret = Findbyname(p, name);
    if (ret == -1)
    {
        printf("要修改的联系人不存在\n");
        return;
    }
    else
    {
        printf("请输入联系人的姓名\n");
        scanf("%s", p->data[ret].name);//[p->sz]data数组的下标
        printf("请输入联系人的性别\n");
        scanf("%s", p->data[ret].set);
        printf("请输入联系人的年龄\n");
        scanf("%d", &(p->data[ret].age));//age为int 变量要取地址
        printf("请输入联系人的电话\n");
        scanf("%s", p->data[ret].tele);
        printf("请输入联系人的地址 \n");
        scanf("%s", p->data[ret].addr);
        printf("修改成功\n");
    }
}

int name_qsort(const void* e1, const void* e2)
{
    return strcmp(((peoinfo*)e1)->name, ((peoinfo*)e2)->name);
}

void Sortcontack(contack* p)
{
    //根据姓名首字母进行排序联系人
    if (p->sz == 0)
    {
        printf("通讯录为空, 无法排序\n");
    }
    else
    {
        //使用qsort进行快速排序
        qsort(p, p->sz, sizeof(peoinfo), name_qsort);
        Printcontack(p);//调用打印函数
        printf("排序成功\n");
    }
}

很高兴能够为大家带来帮助,码字不易,如果大家觉得我这篇文章对你有帮助的话可以点个赞!!!

C语言实现通讯录(简易版)_第5张图片
C语言实现通讯录(简易版)_第6张图片

你可能感兴趣的:(C语言,c语言,开发语言)