评论

收藏

[C++] c语言实现简易通讯录(代码+分析)

编程语言 编程语言 发布于:2021-08-08 15:21 | 阅读数:301 | 评论:0

通讯录

1、需求

  • 存放1000人的好友信息(名字、电话、性别、住址、年龄)
  • 增加好友信息
  • 删除指定名字的好友信息
  • 修改好友信息
  • 查找好友信息
  • 显示(打印)好友信息
  • 排序

2、分析

  • 搭建项目框架
test.c    用于实现测试代码,作为程序的入口
contact.c 用于实现项目的主逻辑(函数的定义)
contact.h 函数的声明

  • 通讯录数据创建
创建好友信息(结构体类型),成员包括:名字、电话、性别、住址、年龄
声明并创建好友信息数组(1000个元素)
注:可封装数组和当前数组大小于结构体类型中

  • 初始化通讯录
将通讯录的成员的内存设置为0

  • 功能实现
增加好友

  • 判断好友个数是否会超过数组
  • 增加好友信息
  • 好友个数+1
显示通讯录:遍历显示
删除好友

  • 判断好友是否存在
  • 数组删除元素

    • 向前挪动被删除元素后的元素
    • 数组长度-1

查找好友

  • 判断好友是否存在
  • 查找数组元素并打印
修改好友

  • 判断好友是否存在
  • 修改元素信息
排序:qsort排序

3、实现
1、页面框架搭建

  • 循环显示页面:输入0-6实现退出、增加、删除等功能
enum Option
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SHOW,
SORT
};
int main()
{
int input = 0;
do
 {
    PrintMenu();
    input_err:
    printf("请选择>: ");
    scanf("%d", &input);
    system("cls");
    switch (input)
    {
      case ADD:   
        AddFriend(&contact);
        break;
      case DEL:
        DeleteFriend(&contact);
        break;
      case SEARCH:
        SearchFriend(&contact);
        break;
      case MODIFY:
        ModifyFriend(&contact);
        break;
      case SHOW:
        ShowContact(&contact);
        break;
      case SORT:
        SortFriend(&contact);
        break;
      case EXIT:
        printf("GOODBYE!\n");
        break;
      default:
        printf("输入错误,请重新输入\n");
        goto input_err;
    }
  } while (input);
  return 0;
}2、通讯录创建与初始化
定义结构体存放通讯录数据,其中成员包括好友列表通讯录大小两个成员
好友列表可定义为结构体,其中成员包括姓名年龄性别电话住址
定义初始化函数:直接利用内存函数将结构体数组设置为0
#define LIST_MAX 100define NAME_MAX 20define TELE_MAX 12define ADDR_MAX 20
typedef enum Gender
{
UNKNOWN,
MALE,
FEMALE,
}Gender;
typedef struct FriendInfo
{
char name[LIST_MAX];
int age;
Gender gender;
char tele[TELE_MAX];
char address[ADDR_MAX];
}FriendInfo;
typedef struct Contact
{
// 存放1000人信息
FriendInfo friendList[LIST_MAX];
// 列表大小
int size;
}Contact;
// 初始化通讯录
void InitContact(Contact contact_p)
{
memset(contact_p->friendList, 0, sizeof(contact_p->friendList));
contact_p->size = 0;
}
int main()
{ 
// 创建通讯录
Contact contact = { 0 };
// 初始化通讯录
InitContact(&contact);
return 0;
}
3、实现功能函数
1. 添加好友
注:由于添加好友的操作与修改好友的操作会涉及代码复用,故封装修改信息操作为一个函数
// 修改数组元素
static void ModifyElement(Contact contact_p, int i)
{
// 增加好友信息
printf("请输入名字>: ");
scanf("%s", contact_p->friendList[i].name);
printf("请输入年龄>: ");
scanf("%d", &(contact_p->friendList[i].age));
char tmp[20] = "";
modify_friend_err:
printf("请输入性别>: ");
scanf("%s", tmp);
if (strcmp(tmp, "male") == 0)
 {
    contact_p->friendList[i].gender = MALE;
  }
  else if (strcmp(tmp, "female") == 0)
  {
    contact_p->friendList[i].gender = FEMALE;
  }
  else if (strcmp(tmp, "unknown") == 0)
  {
    contact_p->friendList[i].gender = UNKNOWN;
  }
  else
  {
    printf("输入错误,请重新输入\n");
    goto modify_friend_err;
  }
printf("请输入电话>: ");
scanf("%s", contact_p->friendList.tele);
printf("请输入地址>: ");
scanf("%s", contact_p->friendList.address);
}
// 添加好友函数
void AddFriend(Contact* contact_p)
{if (contact_p->size < LIST_MAX)
{
// 增加元素
    ModifyElement(contact_p, contact_p-&gt;size);
// 元素+1
    contact_p-&gt;size++;
    printf("好友添加成功!\n");
  }
  else
  {
    printf("通讯录已满,无法继续增加\n");
  }
}2. 删除好友
注:由于删除、查询、修改操作会重复使用通过姓名查找元素的逻辑,故封装为一个函数,其中函数接收一个函数指针作为回调函数,以分别处理上述三种逻辑
// 根据名字查找数组中的元素,并完成指定逻辑
static int FindByName(Contact contact_p, char name, void(*callback)(Contact, int))
{
int size = contact_p->size;
for (int i = 0; i < size; i++)
 {
    if (strcmp(name, contact_p-&gt;friendList[i].name) == 0)
    {
      callback(contact_p, i);
      return 1;
    }
  }
  return 0;
}
// 删除好友函数中的回调函数
static void DeleteElement(Contact contact_p, int i)
{int size = contact_p->size;
// 删除元素
for (int j = i; j < size - 1; j++)
{
contact_p-&gt;friendList[j] = contact_p-&gt;friendList[j + 1];
  }
  // 数组长度-1
  contact_p-&gt;size--;
}
// 删除好友函数
void DeleteFriend(Contact* contact_p)
{char input[NAME_MAX] = "";
int size = contact_p->size;
printf("请输入需要删除的好友的姓名:>");
scanf("%s", input);
int res = FindByName(contact_p, input, DeleteElement);
if (res)
{
printf("删除成功!\n");
  }
  else
  {
    printf("您所输入的好友不存在\n");
  }
}3. 查询好友
// 查找好友函数中的回调函数
static void ShowFriendInfo(const Contact contact_p, int i)
{
printf("================================\n");
printf("姓名:%s\n", contact_p->friendList[i].name);
printf("年龄:%d\n", contact_p->friendList[i].age);
switch (contact_p->friendList[i].gender)
 {
case MALE:
    printf("性别:男\n");
    break;
  case FEMALE:
    printf("性别:女\n");
    break;
  case UNKNOWN:
    printf("性别:未知\n");
    break;
  }
  printf("电话:%s\n", contact_p-&gt;friendList[i].tele);
  printf("地址:%s\n", contact_p-&gt;friendList[i].address);
  printf("================================\n");
}
// 查找好友信息
void SearchFriend(Contact contact_p)
{char input[NAME_MAX] = "";
int size = contact_p->size;
printf("请输入需要查找的好友的姓名:>");
scanf("%s", input);
int res = FindByName(contact_p, input, ShowFriendInfo);
if (!res)
{
printf("您所输入的好友不存在\n");
  }
}4. 修改好友
// 修改好友函数中的回调函数static void ModifyFriendInfo(Contact* contact_p, int i)
{printf("已找到%s,根据提示输入修改值\n", contact_p->friendList.name);
ModifyElement(contact_p, i);
}
// 修改好友信息
void ModifyFriend(Contact contact_p)
{char input[NAME_MAX] = "";
int size = contact_p->size;
printf("请输入需要修改的好友的姓名:>");
scanf("%s", input);
int res = FindByName(contact_p, input, ModifyFriendInfo);
if (res)
{
printf("修改成功!\n");
}
else
{
printf("您所输入的好友不存在\n");
  }
}5. 显示通讯录
遍历好友列表,打印信息
// 显示好友列表函数
void ShowContact(const Contact contact_p)
{
int size = contact_p->size;
if (!size)
 {
    printf("通讯录为空\n");
  }
  else
  {
    for (int i = 0; i &lt; size; i++)
    {
      ShowFriendInfo(contact_p, i);
    }
  }
}6. 排序
通过库函数qsort实现不同类型的快速排序
// 排序函数回调
static int CompairName(const void* e1, const void e2)
{
return strcmp(((FriendInfo)e1)->name, ((FriendInfo*)e2)->name);
}
static int CompairAge(const void e1, const void e2)
{
return ((FriendInfo*)e1)->age - ((FriendInfo)e2)->age;
}
static int CompairGender(const void e1, const void* e2)
{
return ((FriendInfo)e1)->gender - ((FriendInfo)e2)->gender;
}
static int CompairTele(const void* e1, const void e2)
{
return strcmp(((FriendInfo)e1)->tele, ((FriendInfo*)e2)->tele);
}
static int CompairAddress(const void e1, const void e2)
{
return strcmp(((FriendInfo*)e1)->address, ((FriendInfo)e2)->address);
}
// 排序
void SortFriend(Contact contact_p)
{
char val[20] = "";
printf("请输入需要根据什么值进行排序(姓名、年龄、性别、电话、地址):>");
scanf("%s", val);
if (strcmp(val, "姓名") == 0)
 {
    qsort(contact_p-&gt;friendList,
      contact_p-&gt;size,
      sizeof(contact_p-&gt;friendList[0]),
      CompairName);
  }
  else if (strcmp(val, "年龄") == 0)
  {
    qsort(contact_p-&gt;friendList,
      contact_p-&gt;size,
      sizeof(contact_p-&gt;friendList[0]),
      CompairAge);
  }
  else if (strcmp(val, "性别") == 0)
  {
    qsort(contact_p-&gt;friendList,
      contact_p-&gt;size,
      sizeof(contact_p-&gt;friendList[0]),
      CompairGender);
  }
  else if (strcmp(val, "电话") == 0)
  {
    qsort(contact_p-&gt;friendList,
      contact_p-&gt;size,
      sizeof(contact_p-&gt;friendList[0]),
      CompairTele);
  }
  else if (strcmp(val, "住址") == 0)
  {
    qsort(contact_p-&gt;friendList,
      contact_p-&gt;size,
      sizeof(contact_p-&gt;friendList[0]),
      CompairAddress);
  }
  else
  {
    printf("输入错误\n");
    return;
  }
  printf("排序成功!\n");
}
4、完整代码
1、test.c文件
#define _CRT_SECURE_NO_WARNINGSinclude <stdio.h>include <Windows.h>include "contact.h"
void PrintMenu()
{
printf("      通  讯  录     \n");
printf("******************************\n");
printf("******1. ADD    2. DEL******\n");
printf("******3. SEARCH   4. MODIFY***\n");
printf("******5. SHOW   6. SORT*****\n");
printf("******************************\n");
printf("***********************0. EXIT\n");
printf("******************************\n");
}
int main()
{
int input = 0;
// 创建通讯录
Contact contact = { 0 };
// 初始化通讯录
InitContact(&contact);
do
 {
    PrintMenu();
  input_err:
    printf("请选择&gt;: ");
    scanf("%d", &amp;input);
    system("cls");
    switch (input)
    {
    case ADD:   
      AddFriend(&amp;contact);
      break;
    case DEL:
      DeleteFriend(&amp;contact);
      break;
    case SEARCH:
      SearchFriend(&amp;contact);
      break;
    case MODIFY:
      ModifyFriend(&amp;contact);
      break;
    case SHOW:
      ShowContact(&amp;contact);
      break;
    case SORT:
      SortFriend(&amp;contact);
      break;
    case EXIT:
      printf("GOODBYE!\n");
      break;
    default:
      printf("输入错误,请重新输入\n");
      goto input_err;
    }
  } while (input);
return 0;
}2、contact.h文件
#pragma once
define LIST_MAX 100define NAME_MAX 20define TELE_MAX 12define ADDR_MAX 20
enum Option
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SHOW,
SORT
};
typedef enum Gender
{
UNKNOWN,
MALE,
FEMALE,
}Gender;
typedef struct FriendInfo
{
char name[LIST_MAX];
int age;
Gender gender;
char tele[TELE_MAX];
char address[ADDR_MAX];
}FriendInfo;
typedef struct Contact
{
// 存放1000人信息
FriendInfo friendList[LIST_MAX];
// 列表大小
int size;
}Contact;
void InitContact(Contact contact_p);
void AddFriend(Contact contact_p);
void ShowContact(const Contact* contact_p);
void DeleteFriend(Contact contact_p);
void SearchFriend(Contact contact_p);
void ModifyFriend(Contact* contact_p);
void SortFriend(Contact* contact_p);
3、contact.c文件
#define _CRT_SECURE_NO_WARNINGSinclude <stdio.h>include <string.h>include <stdlib.h>include "contact.h"
// *******************************************************************
//                 工具函数
// *******************************************************************
// 根据名字查找数组中的元素,并完成指定逻辑
static int FindByName(Contact contact_p, char name, void(*callback)(Contact, int))
{
int size = contact_p->size;
for (int i = 0; i < size; i++)
 {
    if (strcmp(name, contact_p-&gt;friendList[i].name) == 0)
    {
      callback(contact_p, i);
      return 1;
    }
  }
  return 0;
}
// 修改数组元素
static void ModifyElement(Contact
contact_p, int i)
{// 增加好友信息
printf("请输入名字>: ");
scanf("%s", contact_p->friendList.name);
printf("请输入年龄>: ");
scanf("%d", &(contact_p->friendList.age));
char tmp[20] = "";
modify_friend_err:
printf("请输入性别>: ");
scanf("%s", tmp);
if (strcmp(tmp, "male") == 0)
{
contact_p-&gt;friendList[i].gender = MALE;
  }
  else if (strcmp(tmp, "female") == 0)
  {
    contact_p-&gt;friendList[i].gender = FEMALE;
  }
  else if (strcmp(tmp, "unknown") == 0)
  {
    contact_p-&gt;friendList[i].gender = UNKNOWN;
  }
  else
  {
    printf("输入错误,请重新输入\n");
    goto modify_friend_err;
  }
printf("请输入电话>: ");
scanf("%s", contact_p->friendList.tele);
printf("请输入地址>: ");
scanf("%s", contact_p->friendList.address);
}
// *******************************************************************
// *******************************************************************//                                回调函数
// *******************************************************************
// 删除好友函数中的回调函数
static void DeleteElement(Contact contact_p, int i)
{int size = contact_p->size;
// 删除元素
for (int j = i; j < size - 1; j++)
{
contact_p-&gt;friendList[j] = contact_p-&gt;friendList[j + 1];
  }
  // 数组长度-1
  contact_p-&gt;size--;
}
// 查找好友函数中的回调函数
static void ShowFriendInfo(const Contact
contact_p, int i)
{printf("================================\n");
printf("姓名:%s\n", contact_p->friendList.name);
printf("年龄:%d\n", contact_p->friendList.age);
switch (contact_p->friendList.gender)
{
case MALE:
printf("性别:男\n");
    break;
  case FEMALE:
    printf("性别:女\n");
    break;
  case UNKNOWN:
    printf("性别:未知\n");
    break;
  }
  printf("电话:%s\n", contact_p-&gt;friendList[i].tele);
  printf("地址:%s\n", contact_p-&gt;friendList[i].address);
  printf("================================\n");
}
// 修改好友函数中的回调函数
static void ModifyFriendInfo(Contact* contact_p, int i)
{printf("已找到%s,根据提示输入修改值\n", contact_p->friendList.name);
ModifyElement(contact_p, i);
}
// 排序函数回调
static int CompairName(const void e1, const void e2)
{return strcmp(((FriendInfo*)e1)->name, ((FriendInfo)e2)->name);
}static int CompairAge(const void
e1, const void* e2)
{return ((FriendInfo)e1)->age - ((FriendInfo)e2)->age;
}static int CompairGender(const void* e1, const void e2)
{return ((FriendInfo
)e1)->gender - ((FriendInfo*)e2)->gender;
}static int CompairTele(const void e1, const void e2)
{return strcmp(((FriendInfo*)e1)->tele, ((FriendInfo)e2)->tele);
}static int CompairAddress(const void
e1, const void* e2)
{return strcmp(((FriendInfo)e1)->address, ((FriendInfo)e2)->address);
}
// *******************************************************************
// *******************************************************************//                             主功能函数
// *******************************************************************
// 初始化通讯录
void InitContact(Contact contact_p)
{memset(contact_p->friendList, 0, sizeof(contact_p->friendList));
contact_p->size = 0;
}
// 添加好友函数
void AddFriend(Contact
contact_p)
{if (contact_p->size < LIST_MAX)
{
// 增加元素
    ModifyElement(contact_p, contact_p-&gt;size);
// 元素+1
    contact_p-&gt;size++;
    printf("好友添加成功!\n");
  }
  else
  {
    printf("通讯录已满,无法继续增加\n");
  }
}
// 显示好友列表函数
void ShowContact(const Contact* contact_p)
{int size = contact_p->size;
if (!size)
{
printf("通讯录为空\n");
  }
  else
  {
    for (int i = 0; i &lt; size; i++)
    {
      ShowFriendInfo(contact_p, i);
    }
  }
}
// 删除好友函数
void DeleteFriend(Contact contact_p)
{char input[NAME_MAX] = "";
int size = contact_p->size;
printf("请输入需要删除的好友的姓名:>");
scanf("%s", input);
int res = FindByName(contact_p, input, DeleteElement);
if (res)
{
printf("删除成功!\n");
  }
  else
  {
    printf("您所输入的好友不存在\n");
  }
}
// 查找好友信息
void SearchFriend(Contact
contact_p)
{char input[NAME_MAX] = "";
int size = contact_p->size;
printf("请输入需要查找的好友的姓名:>");
scanf("%s", input);
int res = FindByName(contact_p, input, ShowFriendInfo);
if (!res)
{
printf("您所输入的好友不存在\n");
  }
}
// 修改好友信息
void ModifyFriend(Contact* contact_p)
{char input[NAME_MAX] = "";
int size = contact_p->size;
printf("请输入需要修改的好友的姓名:>");
scanf("%s", input);
int res = FindByName(contact_p, input, ModifyFriendInfo);
if (res)
{
printf("修改成功!\n");
}
else
{
printf("您所输入的好友不存在\n");
  }
}
// 排序
void SortFriend(Contact* contact_p)
{char val[20] = "";
printf("请输入需要根据什么值进行排序(姓名、年龄、性别、电话、地址):>");
scanf("%s", val);
if (strcmp(val, "姓名") == 0)
{
qsort(contact_p-&gt;friendList,
      contact_p-&gt;size,
      sizeof(contact_p-&gt;friendList[0]),
      CompairName);
  }
  else if (strcmp(val, "年龄") == 0)
  {
    qsort(contact_p-&gt;friendList,
      contact_p-&gt;size,
      sizeof(contact_p-&gt;friendList[0]),
      CompairAge);
  }
  else if (strcmp(val, "性别") == 0)
  {
    qsort(contact_p-&gt;friendList,
      contact_p-&gt;size,
      sizeof(contact_p-&gt;friendList[0]),
      CompairGender);
  }
  else if (strcmp(val, "电话") == 0)
  {
    qsort(contact_p-&gt;friendList,
      contact_p-&gt;size,
      sizeof(contact_p-&gt;friendList[0]),
      CompairTele);
  }
  else if (strcmp(val, "住址") == 0)
  {
    qsort(contact_p-&gt;friendList,
      contact_p-&gt;size,
      sizeof(contact_p-&gt;friendList[0]),
      CompairAddress);
  }
  else
  {
    printf("输入错误\n");
    return;
  }
  printf("排序成功!\n");
}
关注下面的标签,发现更多相似文章