C语言实现简单通讯录

C语言实现简单通讯录

前言

  1. 通讯录中内容包括联系人姓名、年龄、性别、电话号码、住址(省、市)。
  2. 使用C语言简单实现通讯录,并实现增、删、改、查(按姓名)、排序(按姓名)、清空通讯录功能。
  3. 分别实现静态版本和动态版本。
  4. 编译器:CLion。

静态版本通讯录

通讯录中内容实现

  • 由于通讯录中内容需要具备联系人姓名、年龄等信息,因此使用结构体构造通讯录人物信息。类型名为PeoInfo

    • typedef struct PeoInfo
      {
          char name[NAME_MAX]; // 姓名
          char sex[SEX_MAX]; // 性别
          int age; // 年龄
          char tele[TELE_MAX]; // 电话
          Addr addr; // 家庭住址
      }PeoInfo; // 重命名为PeoInfo
      
    • 其中家庭住址需要包括省、市信息,因此使用结构体嵌套,构造一个类型名为Addr的结构体。

    • typedef struct Addr
      {
          char prov[PROV_MAX]; // 省
          char city[CITY_MAX]; // 市
      }Addr;
      
    • 为方便后续信息扩容修改,使用#define定义宏

    • #define DATA_MAX 1000
      #define NAME_MAX 20
      #define SEX_MAX 7
      #define TELE_MAX 12
      #define PROV_MAX 10
      #define CITY_MAX 10
      

通讯录菜单功能实现

  • 构建一个菜单,菜单中设定增、删、改、查、排序、打印功能。

    • void menu()
      {
          printf("|--------------------------------|\n");
          printf("|------ 1. add     2. del -------|\n");
          printf("|------ 3.search 4.modify -------|\n");
          printf("|------ 5.sort    6.print -------|\n");
          printf("|------ 7.clean   0.exit  -------|\n");
          printf("|--------------------------------|\n");
      }
      
    • 菜单展示效果

  • 实现选项功能

    • enum Option
      {
          EXIT,
          ADD,
          DEL,
          SEARCH,
          MODIFY,
          SORT,
          PRINT,
          CLEAN
      };
      int input = 0;
      do {
              menu();
              printf("请选择功能:>");
              scanf("%d", &input);
              switch (input) {
                  case ADD: // 增
                      break;
                  case DEL: // 删
                      break;
                  case SEARCH: // 查
                      break;
                  case MODIFY: // 改
                      break;
                  case SORT: // 排序
                      break;
                  case PRINT: // 打印
                      break;
                  case CLEAN: // 清空通讯录
                      break;
                  case EXIT:
                      printf("退出通讯录\n");
                      break;
                  default:
                      printf("输入错误,请重新输入\n");
                      break;
              }
          }while(input);
      

通讯录结构体

  • 若只构建PeoInfo结构体,实现增删改查功能时,需传递PeoInfo结构体和数据数量,及其不方便,因此再次封装一个通讯录结构体,结构体成员包含PeoInfo和数据数量sz

    • typedef struct Contact
      {
          PeoInfo data[DATA_MAX];
          int sz;
      }Contact;
      

打印功能实现

  • 实现打印通讯录功能printContact

    • 逐条打印,打印联系人姓名、性别、年龄、电话号码、地址

    • 样式效果:

      • 姓名      性别          年龄         电话          住址
        ---------------------------------------------------
        
    • 代码实现

      • void printContact(const Contact* con)
        {
            // 打印通讯录函数
            int i = 0;
            printf("%-20s\t%-10s\t%-5s\t%-15s\t%-20s\n", "姓名", "性别", "年龄", "电话号码", "住址");
            printf("----------------------------------------------------------------------------\n");
            for(i = 0; i < con->sz; i++)
            {
                printf("%-20s\t%-10s\t%-5d\t%-15s\t%-10s%-10s\n", con->data[i].name, con->data[i].sex, con->data[i].age, con->data[i].tele, con->data[i].addr.prov, con->data[i].addr.city);
            }
        }
        
      • 形式参数使用const修饰,因为功能只是打印通讯录列表,不需要修改其内容,使用const修饰增加代码健壮性。

      • con->sz表示通讯录中数据个数

    • 效果展示

      • 打印通讯录功能展示.png

初始化通讯录

  • 创建通讯录结构体对象Contact con

  • 编写函数初始化con中内容,使PeoInfo data数组中的内容全置为0,通讯录中信息个数sz置为0。

    • void initContact(Contact* con)
      {
          con->sz = 0;
          memset(con->data, 0, sizeof(PeoInfo));
      }
      
memset函数解释
  • memset函数图片.png
  • 功能:将指定的内存块设置成指定值。
  • 参数解释:
    • void* ptr要设置内存块的起始地址指针。
    • int value要设置的值。
    • size_t num要设置值的内存字节数。

增删改查功能

增加通讯录信息功能addContact
  • 依次输入练习人姓名、性别、年龄、电话号码、省、市。

  • 样式效果:

    • 请输入姓名:>
      请输入性别:>
      请输入年龄:>
      请输入电话号码:>
      请输入省份:>
      请输入城市:>
      
  • 将输入信息添加到通讯录对象中。

    • void addContact(Contact* con)
      {
          // 添加通讯录信息函数
          // 静态版本
         if(con->sz == DATA_MAX)
          {
              // 判断通讯录是否已满
              printf("通讯录已满,无法添加\n");
              return;
          }
      
          printf("请输入姓名:>");
          scanf("%s", con->data[con->sz].name);
          printf("请输入性别:>");
          scanf("%s", con->data[con->sz].sex);
          printf("请输入年龄:>");
          scanf("%d", &(con->data[con->sz].age));
          printf("请输入电话号码:>");
          scanf("%s", con->data[con->sz].tele);
          printf("请输入省份:>");
          scanf("%s", con->data[con->sz].addr.prov);
          printf("请输入城市:>");
          scanf("%s", con->data[con->sz].addr.city);
      
          (con->sz)++; // 添加一条数据后,con->sz自加1,保证添加的数据始终是要添加位置的加标。
      }
      
删除通讯录中信息功能delContact
  • 根据姓名,查找要删除的元素的下标,若找不到该元素,返回-1。

    • int findByName(const Contact* con, char name[])
      {
          int i = 0;
          for(i = 0; i < con->sz; i++)
          {
              if(strcmp(con->data[i].name, name) == 0)
              {
                  return i;
              }
          }
          return -1;
      }
      
  • 删除元素功能即将要删除的元素覆盖即可。

    • 删除通讯录元素分析图.png

    • 注:最后一个元素并没有置空,只是使用con->sz--不再访问最后一个元素。

    • 代码实现:

      • void delContact(Contact* con)
        {
            if(con->sz == 0)
            {
                printf("通讯录已空,无法删除\n");
                return;
            }
            char name[NAME_MAX] = {0};
            printf("请输入要删除的姓名:>");
            scanf("%s", name);
            // 按照名字删除
            int i = findByName(con, name);
            if(i == -1)
            {
                printf("没有要删除的人\n");
            }
            else
            {
                memmove(con->data + i, con->data + i + 1, (con->sz - 1 - i) * sizeof(con->data[0]));
                con->sz--;
            }
        }
        
memmove函数解释
  • memmove函数.png
  • 功能:移动内存块,将指定字节数的内存数据移动到指定目标地址处。
  • 形参解释:
    • void* destination目标地址指针。
    • const void* source源数据地址指针,由于不需要改变源数据,所以使用const修饰。
    • size_t num字节数。
查询通讯录内容并打印searchByName
  • 根据名字查询数据,并打印出来。可以使用自定义函数findByName来查找下标。

    • void searchByName(const Contact* con)
      {
          char name[NAME_MAX] = {0};
          // 按照名字查找函数
          printf("请输入要查找的姓名:>");
          scanf("%s", name);
          int i = findByName(con, name);
          if(i == -1)
          {
              printf("查不到该用户\n");
          }
          else
          {
              printf("%-20s\t%-10s\t%-5s\t%-15s\t%-20s\n", "姓名", "性别", "年龄", "电话号码", "住址");
              printf("----------------------------------------------------------------------------\n");
              printf("%-20s\t%-10s\t%-5d\t%-15s\t%-10s%-10s\n", con->data[i].name, con->data[i].sex, con->data[i].age, con->data[i].tele, con->data[i].addr.prov, con->data[i].addr.city);
          }
      }
      
  • 效果展示:

    • 查找通讯录信息效果展示.png
修改通讯录信息功能modifyContact
  • 根据姓名查找需要修改的信息的下标,然后进行指定信息修改。

    • void modifyContact(Contact* con)
      {
          if(con->sz == 0)
          {
              printf("通讯录已空,没有要修改的人\n");
          }
          char name[NAME_MAX] = {0};
          printf("请输入要修改的姓名:>");
          scanf("%s", name);
      
          int i = findByName(con, name);
          if(i == -1)
          {
              printf("没有要修改的人\n");
          }
          else
          {
              printf("请输入姓名:>");
              scanf("%s", con->data[i].name);
              printf("请输入性别:>");
              scanf("%s", con->data[i].sex);
              printf("请输入年龄:>");
              scanf("%d", &(con->data[i].age));
              printf("请输入电话号码:>");
              scanf("%s", con->data[i].tele);
              printf("请输入省份:>");
              scanf("%s", con->data[i].addr.prov);
              printf("请输入城市:>");
              scanf("%s", con->data[i].addr.city);
          }
      }
      

排序功能sortByName

  • 根据姓名进行排序,使用库函数qsort进行快排。

    • void sortByName(Contact* con)
      {
          // 按照名字排序
          qsort(con->data, con->sz, sizeof(con->data[0]), cmpByName);
      }
      
    • int cmpByName(const void* e1, const void* e2)
      {
          return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
      }
      
qsort函数解释
  • qsort函数.png
  • 功能:通过指定顺序排序数组中元素
  • 形参解释:
    • void* base需要排序的数组起始位置。
    • size_t num需要排序的元素个数。
    • size_t size排序元素大小(字节数)。
    • int (*compar)(const void*, const void*)函数指针,指定回调函数,指定排序方式。

清空通讯录功能cleanContact

  • 只要将con->sz置为0,即可实现该功能。

    • void cleanContact(Contact* con)
      {
          con->sz = 0;
      }
      

完整代码

// 头文件包含,函数声明,结构体构建,枚举变量构建Contact.h文件


#ifndef C_CODE_CONTACT_H
#define C_CODE_CONTACT_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>


// 数据宏
#define DATA_MAX 1000
#define NAME_MAX 20
#define SEX_MAX 7
#define TELE_MAX 12
#define PROV_MAX 10
#define CITY_MAX 10


// 选项枚举
enum Option
{
    EXIT,
    ADD,
    DEL,
    SEARCH,
    MODIFY,
    SORT,
    PRINT,
    CLEAN
};

// 创建地址结构体
typedef struct Addr
{
    char prov[PROV_MAX];
    char city[CITY_MAX];
}Addr;
// 创建人员信息结构体
typedef struct PeoInfo
{
    char name[NAME_MAX]; // 姓名
    char sex[SEX_MAX]; // 性别
    int age; // 年龄
    char tele[TELE_MAX]; // 电话
    Addr addr; // 家庭住址
}PeoInfo;
// 创建通讯录结构体
// 静态版本
typedef struct Contact
{
    PeoInfo data[DATA_MAX];
    int sz;
}Contact;

// 函数声明
void initContact(Contact* con);

void addContact(Contact* con);

void printContact(const Contact* con);

void searchByName(const Contact* con);

void sortByName(Contact* con);

void delContact(Contact* con);

void modifyContact(Contact* con);

void cleanContact(Contact* con);

void distroyContact(Contact* con);


#endif //C_CODE_CONTACT_H
// 通讯录功能实现Contact.c文件

#include "Contact.h"

void initContact(Contact* con)
{

    con->sz = 0;
    memset(con->data, 0, sizeof(PeoInfo));
}


void addContact(Contact* con)
{
    // 添加通讯录信息函数
    // 静态版本
    if(con->sz == DATA_MAX)
    {
        printf("通讯录已满,无法添加\n");
        return;
    }

    printf("请输入姓名:>");
    scanf("%s", con->data[con->sz].name);
    printf("请输入性别:>");
    scanf("%s", con->data[con->sz].sex);
    printf("请输入年龄:>");
    scanf("%d", &(con->data[con->sz].age));
    printf("请输入电话号码:>");
    scanf("%s", con->data[con->sz].tele);
    printf("请输入省份:>");
    scanf("%s", con->data[con->sz].addr.prov);
    printf("请输入城市:>");
    scanf("%s", con->data[con->sz].addr.city);

    (con->sz)++;
}

void printContact(const Contact* con)
{
    // 打印通讯录函数
    int i = 0;
    printf("%-20s\t%-10s\t%-5s\t%-15s\t%-20s\n", "姓名", "性别", "年龄", "电话号码", "住址");
    printf("----------------------------------------------------------------------------\n");
    for(i = 0; i < con->sz; i++)
    {
        printf("%-20s\t%-10s\t%-5d\t%-15s\t%-10s%-10s\n", con->data[i].name, con->data[i].sex, con->data[i].age, con->data[i].tele, con->data[i].addr.prov, con->data[i].addr.city);
    }
}

int findByName(const Contact* con, char name[])
{
    int i = 0;
    for(i = 0; i < con->sz; i++)
    {
        if(strcmp(con->data[i].name, name) == 0)
        {
            return i;
        }
    }
    return -1;
}

void searchByName(const Contact* con)
{
    char name[NAME_MAX] = {0};
    // 按照名字查找函数
    printf("请输入要查找的姓名:>");
    scanf("%s", name);
    int i = findByName(con, name);
    if(i == -1)
    {
        printf("查不到该用户\n");
    }
    else
    {
        printf("%-20s\t%-10s\t%-5s\t%-15s\t%-20s\n", "姓名", "性别", "年龄", "电话号码", "住址");
        printf("----------------------------------------------------------------------------\n");
        printf("%-20s\t%-10s\t%-5d\t%-15s\t%-10s%-10s\n", con->data[i].name, con->data[i].sex, con->data[i].age, con->data[i].tele, con->data[i].addr.prov, con->data[i].addr.city);
    }
}

void delContact(Contact* con)
{
    if(con->sz == 0)
    {
        printf("通讯录已空,无法删除\n");
        return;
    }
    char name[NAME_MAX] = {0};
    printf("请输入要删除的姓名:>");
    scanf("%s", name);
    // 按照名字删除
    int i = findByName(con, name);
    if(i == -1)
    {
        printf("没有要删除的人\n");
    }
    else
    {
        memmove(con->data + i, con->data + i + 1, (con->sz - 1 - i) * sizeof(con->data[0]));
        con->sz--;
    }
}

void modifyContact(Contact* con)
{
    if(con->sz == 0)
    {
        printf("通讯录已空,没有要修改的人\n");
    }
    char name[NAME_MAX] = {0};
    printf("请输入要修改的姓名:>");
    scanf("%s", name);

    int i = findByName(con, name);
    if(i == -1)
    {
        printf("没有要修改的人\n");
    }
    else
    {
        printf("请输入姓名:>");
        scanf("%s", con->data[i].name);
        printf("请输入性别:>");
        scanf("%s", con->data[i].sex);
        printf("请输入年龄:>");
        scanf("%d", &(con->data[i].age));
        printf("请输入电话号码:>");
        scanf("%s", con->data[i].tele);
        printf("请输入省份:>");
        scanf("%s", con->data[i].addr.prov);
        printf("请输入城市:>");
        scanf("%s", con->data[i].addr.city);
    }
}

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

void sortByName(Contact* con)
{
    // 按照名字排序
    qsort(con->data, con->sz, sizeof(con->data[0]), cmpByName);
}

void cleanContact(Contact* con)
{
    con->sz = 0;
}

void distroyContact(Contact* con)
{
    free(con->data);
    con->sz = 0;
    con->capacity = 0;
    con->data = NULL;
    printf("销毁成功\n");
}
// 主程序,菜单Main.c文件
#include "Contact.h"



void menu()
{
    printf("|--------------------------------|\n");
    printf("|------ 1. add     2. del -------|\n");
    printf("|------ 3.search 4.modify -------|\n");
    printf("|------ 5.sort    6.print -------|\n");
    printf("|------ 7.clean   0.exit  -------|\n");
    printf("|--------------------------------|\n");
}

void test()
{
    Contact con;
    // 初始化通讯录
    initContact(&con);
    int input = 0;
    do {
        menu();
        printf("请选择功能:>");
        scanf("%d", &input);
        switch (input) {
            case ADD:
                addContact(&con);
                break;
            case DEL:
                delContact(&con);
                break;
            case SEARCH:
                searchByName(&con);
                break;
            case MODIFY:
                modifyContact(&con);
                break;
            case SORT:
                sortByName(&con);
                break;
            case PRINT:
                printContact(&con);
                break;
            case CLEAN:
                cleanContact(&con);
                break;
            case EXIT:
                printf("退出通讯录\n");
                break;
            default:
                printf("输入错误,请重新输入\n");
                break;
        }
    }while(input);
}

int main()
{
    test();
    return 0;
}

动态开辟空间版本通讯录

  • 由于静态版本通讯录初始容量为1000个数据,不能扩容,若数据量比较小太浪费内存空间,因此使用动态开辟空间来优化内存使用。

动态开辟空间库函数介绍

malloc函数
  • malloc函数.png
  • 功能:动态开辟内存块。
  • 形参解释:
    • size_t size开辟空间的大小(字节数)。
  • 若开辟失败,返回NULL。
calloc函数
  • calloc函数.png
  • 功能:动态开辟内存块,初始化内存块数据。
  • 形参解释:
    • size_t num开辟空间指定初始化的值。
    • size_t size开辟空间大小(字节数)。
  • 若开辟失败,返回NULL。
realloc函数
  • realloc函数.png
  • 功能:重新分配内存块,并将之前内存块数据复制到新开辟的内存块,若重新分配的内存块起始地址不是原内存块地址,则释放原内存块。
  • 形参解释:
    • void* ptr需要重新分配内存块的指针。
    • size_t size开辟空间大小(字节数)。
  • 若开辟失败,返回NULL。
动态开辟版本通讯录结构体构建
  • 需要指定扩容值,即数据达到扩容值,开始扩容。

    • typedef struct Contact
      {
          PeoInfo* data; // 通讯录信息指针(需要动态开辟空间)
          int sz; // 通讯录中数据数量
          int capacity; // 扩容值,初始值定为3,之后每次扩容2个
      }Contact;
      
初始化通讯录
  1. 初始容量为3,数据满后,每次扩容2个。

  2. con->sz置为0。

  3. data数组动态扩容。

    • void initContact(Contact* con)
      {
      
          con->sz = 0;
          con->capacity = CAP_MAX;
          PeoInfo* ptr = (PeoInfo*) malloc(CAP_MAX * sizeof(PeoInfo));
          if(ptr == NULL)
          {
              perror("initContact::malloc");
              return;
          }
          con->data = ptr;
          memset(con->data, 0, sizeof(PeoInfo));
      }
      
增加通讯录信息功能addContact
  • 首先判断通讯录信息是否满了。若con->sz == con->capacity即满了,便扩容。

    • void checkCapacity(Contact* con)
      {
          if(con->sz == con->capacity)
          {
              PeoInfo* ptr = (PeoInfo*)realloc(con->data, (con->capacity + 2) * sizeof(PeoInfo));
              if(ptr == NULL)
              {
                  perror("realloc");
                  return;
              }
              con->data = ptr;
              con->capacity += 2;
              printf("增容成功\n");
          }
      }
      
  • 后续增加信息和静态版本一致。

释放动态开辟内存distroyContact
  • 指定退出通讯录时,释放动态开辟内存。

    • void distroyContact(Contact* con)
      {
          free(con->data);
          con->sz = 0;
          con->capacity = 0;
          con->data = NULL;
          printf("销毁成功\n");
      }
      
  • 其余功能与静态版本通讯录一致。

完整代码
// 头文件包含,函数声明,结构体构建,枚举变量构建Contact.h文件


#ifndef C_CODE_CONTACT_H
#define C_CODE_CONTACT_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>


// 数据宏
#define DATA_MAX 1000
#define NAME_MAX 20
#define SEX_MAX 7
#define TELE_MAX 12
#define PROV_MAX 10
#define CITY_MAX 10

#define CAP_MAX 3

// 选项枚举
enum Option
{
    EXIT,
    ADD,
    DEL,
    SEARCH,
    MODIFY,
    SORT,
    PRINT,
    CLEAN
};

// 创建地址结构体
typedef struct Addr
{
    char prov[PROV_MAX];
    char city[CITY_MAX];
}Addr;
// 创建人员信息结构体
typedef struct PeoInfo
{
    char name[NAME_MAX]; // 姓名
    char sex[SEX_MAX]; // 性别
    int age; // 年龄
    char tele[TELE_MAX]; // 电话
    Addr addr; // 家庭住址
}PeoInfo;
// 创建通讯录结构体
// 动态版本
typedef struct Contact
{
    PeoInfo* data;
    int sz;
    int capacity;
}Contact;

// 函数声明
void initContact(Contact* con);

void addContact(Contact* con);

void printContact(const Contact* con);

void searchByName(const Contact* con);

void sortByName(Contact* con);

void delContact(Contact* con);

void modifyContact(Contact* con);

void cleanContact(Contact* con);

void distroyContact(Contact* con);


#endif //C_CODE_CONTACT_H
// 通讯录功能实现Contact.c文件

#include "Contact.h"

void initContact(Contact* con)
{

    con->sz = 0;
    con->capacity = CAP_MAX;
    PeoInfo* ptr = (PeoInfo*) malloc(CAP_MAX * sizeof(PeoInfo));
    if(ptr == NULL)
    {
        perror("initContact::malloc");
        return;
    }
    con->data = ptr;
    memset(con->data, 0, sizeof(PeoInfo));
}


void checkCapacity(Contact* con)
{
    if(con->sz == con->capacity)
    {
        PeoInfo* ptr = (PeoInfo*)realloc(con->data, (con->capacity + 2) * sizeof(PeoInfo));
        if(ptr == NULL)
        {
            perror("realloc");
            return;
        }
        con->data = ptr;
        con->capacity += 2;
        printf("增容成功\n");
    }
}

void addContact(Contact* con)
{
    // 添加通讯录信息函数

    // 动态版本
    checkCapacity(con);
    printf("请输入姓名:>");
    scanf("%s", con->data[con->sz].name);
    printf("请输入性别:>");
    scanf("%s", con->data[con->sz].sex);
    printf("请输入年龄:>");
    scanf("%d", &(con->data[con->sz].age));
    printf("请输入电话号码:>");
    scanf("%s", con->data[con->sz].tele);
    printf("请输入省份:>");
    scanf("%s", con->data[con->sz].addr.prov);
    printf("请输入城市:>");
    scanf("%s", con->data[con->sz].addr.city);

    (con->sz)++;
}

void printContact(const Contact* con)
{
    // 打印通讯录函数
    int i = 0;
    printf("%-20s\t%-10s\t%-5s\t%-15s\t%-20s\n", "姓名", "性别", "年龄", "电话号码", "住址");
    printf("----------------------------------------------------------------------------\n");
    for(i = 0; i < con->sz; i++)
    {
        printf("%-20s\t%-10s\t%-5d\t%-15s\t%-10s%-10s\n", con->data[i].name, con->data[i].sex, con->data[i].age, con->data[i].tele, con->data[i].addr.prov, con->data[i].addr.city);
    }
}

int findByName(const Contact* con, char name[])
{
    int i = 0;
    for(i = 0; i < con->sz; i++)
    {
        if(strcmp(con->data[i].name, name) == 0)
        {
            return i;
        }
    }
    return -1;
}

void searchByName(const Contact* con)
{
    char name[NAME_MAX] = {0};
    // 按照名字查找函数
    printf("请输入要查找的姓名:>");
    scanf("%s", name);
    int i = findByName(con, name);
    if(i == -1)
    {
        printf("查不到该用户\n");
    }
    else
    {
        printf("%-20s\t%-10s\t%-5s\t%-15s\t%-20s\n", "姓名", "性别", "年龄", "电话号码", "住址");
        printf("----------------------------------------------------------------------------\n");
        printf("%-20s\t%-10s\t%-5d\t%-15s\t%-10s%-10s\n", con->data[i].name, con->data[i].sex, con->data[i].age, con->data[i].tele, con->data[i].addr.prov, con->data[i].addr.city);
    }
}

void delContact(Contact* con)
{
    if(con->sz == 0)
    {
        printf("通讯录已空,无法删除\n");
        return;
    }
    char name[NAME_MAX] = {0};
    printf("请输入要删除的姓名:>");
    scanf("%s", name);
    // 按照名字删除
    int i = findByName(con, name);
    if(i == -1)
    {
        printf("没有要删除的人\n");
    }
    else
    {
        memmove(con->data + i, con->data + i + 1, (con->sz - 1 - i) * sizeof(con->data[0]));
        con->sz--;
    }
}

void modifyContact(Contact* con)
{
    if(con->sz == 0)
    {
        printf("通讯录已空,没有要修改的人\n");
    }
    char name[NAME_MAX] = {0};
    printf("请输入要修改的姓名:>");
    scanf("%s", name);

    int i = findByName(con, name);
    if(i == -1)
    {
        printf("没有要修改的人\n");
    }
    else
    {
        printf("请输入姓名:>");
        scanf("%s", con->data[i].name);
        printf("请输入性别:>");
        scanf("%s", con->data[i].sex);
        printf("请输入年龄:>");
        scanf("%d", &(con->data[i].age));
        printf("请输入电话号码:>");
        scanf("%s", con->data[i].tele);
        printf("请输入省份:>");
        scanf("%s", con->data[i].addr.prov);
        printf("请输入城市:>");
        scanf("%s", con->data[i].addr.city);
    }
}

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

void sortByName(Contact* con)
{
    // 按照名字排序
    qsort(con->data, con->sz, sizeof(con->data[0]), cmpByName);
}

void cleanContact(Contact* con)
{
    con->sz = 0;
}

void distroyContact(Contact* con)
{
    free(con->data);
    con->sz = 0;
    con->capacity = 0;
    con->data = NULL;
    printf("销毁成功\n");
}
// 主程序,菜单Main.c文件
#include "Contact.h"



void menu()
{
    printf("|--------------------------------|\n");
    printf("|------ 1. add     2. del -------|\n");
    printf("|------ 3.search 4.modify -------|\n");
    printf("|------ 5.sort    6.print -------|\n");
    printf("|------ 7.clean   0.exit  -------|\n");
    printf("|--------------------------------|\n");
}

void test()
{
    Contact con;
    // 初始化通讯录
    initContact(&con);
    int input = 0;
    do {
        menu();
        printf("请选择功能:>");
        scanf("%d", &input);
        switch (input) {
            case ADD:
                addContact(&con);
                break;
            case DEL:
                delContact(&con);
                break;
            case SEARCH:
                searchByName(&con);
                break;
            case MODIFY:
                modifyContact(&con);
                break;
            case SORT:
                sortByName(&con);
                break;
            case PRINT:
                printContact(&con);
                break;
            case CLEAN:
                cleanContact(&con);
                break;
            case EXIT:
                distroyContact(&con);
                printf("退出通讯录\n");
                break;
            default:
                printf("输入错误,请重新输入\n");
                break;
        }
    }while(input);
}

int main()
{
    test();
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烛九_阴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值