简易通讯录的实现(下)

简介: 简易通讯录的实现(下)

SHOWContact函数(显示)

刚刚我们只是添加成功,可以通过调试来查看是否存放成功,但无法在程序运行台中显示出来,所以我们先来实现显示函数,来将添加成功的联系人显示出来。

void SHOWContact(const Contact* pc)
{
  assert(pc);
  if (pc->sz == 0)
  {
    printf("通讯录为空,无需打印\n");
    return;
  }
  int i = 0;
  //名字  年龄  性别  电话    地址
  //xxx   xxx  xxx  xxx     xxx
  printf("%-20s%-10s%-10s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址");
  for (i = 0; i < pc->sz; i++)
  {
    //打印每个人的信息
    printf("%-20s%-10d%-10s%-12s%-30s\n",
      pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);
  }
}

首先,我们只是显示联系人,不希望其发生改变,所以可以在传入指针中用const来修饰指针pc,之后仍然是断然防止传入指针为空,如果sz也就是记录联系人人数等于0,那么就无需打印通讯录,之后我们为了让打印出来的联系人更加直观所以用printf函数来显示出来data成员的各项数据。之后通过for循环,以及使用pc指针找到sz来遍历data成员,并且全部打印出来就可以了。

FindByName(查找)

我们在实现删除联系人函数功能之前,必须先来找到该成员,包括后面的修改联系人,查找并显示联系人,都需要先找到该联系人,所以我们把找到该联系人的功能,单独封装为一个函数来实现。

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

首先,既然要查找该联系人,那么就需要两个参数,一个是con的地址,通过pc来找到,另一个是要找的联系人的名字,定义一个char型的指针变量来接受,首先我们依然先来断言一下防止传入指针pc为空,之后通过for循环,用pc找到sz来遍历data成员来查找到该联系人,如果找到我们怎么判断名字是否相等,就通过strcmp函数,等于0就说明查找到了,这时候返回i,就能记录当前联系人的下标,如果遍历完了没有找到,我们就返回-1。

DElContact函数(删除)

有了查找函数,接下来我们来实现删除函数功能。

void DELContact(Contact* pc)
{
  char name[NAME_MAX];
  assert(pc);
  if (pc->sz == 0)
  {
    printf("通讯录为空,不可删除\n");
    return;
  }
  printf("请输入你想删除的联系人:");
  scanf("%s", name);
  int ret = FindByName(pc, name);
  if (ret == -1)
  {
    printf("该联系人不存在,无法删除!\n");
    return;
  }
  int i = 0;
  for (i = ret; i < pc->sz-1; i++)
  {
    pc->data[i] = pc->data[i + 1];
  }
  pc->sz--;
  printf("删除该联系人成功!\n");
}

首先依然是接受con用Contact指针变量pc来接受,定义一个char型的name数组,之后依然是断然防止pc为空,如果通过pc找到的sz为0,那么就无法删除联系人。之后提示打印想要删除的联系人,然后通过scanf函数来输入,之后定义一个ret来接受通过FindByName查找到的下标,如果ret等于-1,说明该联系人不存在,不为0,说明存在,之后我们通过for循环让i等于ret,之后遍历到通过pc找到的sz-1,我们把ret之后的每个data成员往前移动一位,这样就实现了删除。最后通过pc找到的sz–,来记录联系人人数。

SearchContact函数(查找并显示)

我们来实现查找并单独打印的函数功能,这个函数实现起来也是十分简单,接下来我们来看一下

void SearchContact(Contact* pc)
{
  assert(pc);
  char name[NAME_MAX];
  printf("请输入想查找的联系人");
  scanf("%s", &name);
  int ret = FindByName(pc, name);
  if (ret == -1)
  {
    printf("该联系人不存在!\n");
    return;
  }
  printf("%-20s%-10s%-10s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址");
  printf("%-20s%-10d%-10s%-12s%-30s\n",
    pc->data[ret].name, pc->data[ret].age, pc->data[ret].sex, pc->data[ret].tele, pc->data[ret].addr);
}

依然是和前面函数一样的指针pc,断言,之后定义一个char型的name数组,提示想要查找的联系人,传参给FindByName来查找并赋值给ret,如果ret等于-1,那么该联系人不存在,否则打印即可。

ModifyContact函数(修改)

这个函数实现起来也是十分简单,我们来一起看一下吧。

void ModifyContact(Contact* pc)
{
  assert(pc);
  char name[NAME_MAX];
  printf("请输入想修改的联系人");
  scanf("%s", &name);
  int ret = FindByName(pc, name);
  if (ret == -1)
  {
    printf("该联系人不存在!\n");
    return;
  }
  printf("请输入姓名:");
  scanf("%s", pc->data[ret].name);
  printf("请输入年龄:");
  scanf("%d", &(pc->data[ret].age));
  printf("请输入性别:");
  scanf("%s", pc->data[ret].sex);
  printf("请输入电话号码:");
  scanf("%s", pc->data[ret].tele);
  printf("请输入住址:");
  scanf("%s", pc->data[ret].addr);
  printf("修改联系人成功!\n");
}

首先依然是同样的pc指针,断言,定义char型的name数组,输入修改联系人名字,通过FindByName函数查找到的下标传给ret,如果等于-1,则说明该联系人不存在,否则直接输入data成员的各项数据,存放到data[ret]中去。

SortContact函数(排序)

我们来实现算是最后一个功能,排序功能。

int compare_name(const void* base,const void* src)
{
  return strcmp(((PeoInfo*)base)->name , ((PeoInfo*)src)->name);
}
int compare_age(const void* base, const void* src)
{
  return (((PeoInfo*)base)->age-((PeoInfo*)src)->age);
}
void SortContact(Contact* pc)
{
  int ret = 0;
  printf("1按名字排序,2按年龄排序\n");
  scanf("%d", &ret);
  if (ret == 1)
  {
      qsort(pc->data, pc->sz, sizeof(PeoInfo), compare_name);
      SHOWContact(pc);
      printf("名字排序成功\n");
  }
  else if (ret == 2)
  {
      qsort(pc->data, pc->sz, sizeof(PeoInfo), compare_age);
      SHOWContact(pc);
      printf("年龄排序成功\n");
  }
  else
  {
    printf("选择错误,返回操作");
  }
}

排序功能,需要我们自定义比较函数,我们先通过ret来选择按名字排序还是年龄排序,之后再不同的情况中同qsort函数来排序后通过SHOWContact函数来显示排序过后的通讯录,即可。两个自定义比较函数,分别强转为PeoInfo类型指针后指向年龄相减,或者指向名字用strcmp函数比较即可。就实现了两个不同的排序情况。

清空通讯录

最后如果我们想要清空通讯录,直接调用初始化函数即可,这样就把所有的数据清空了

可以通过调试监视窗口,确实是清空了。

详细代码

最后给大家分享鄙人代码

test.c

#include"contact.h"
enum Option
{
  EXIT,
  ADD,
  DEL,
  SEARCH,
  MODIFY,
  SHOW,
  SORT,
  EMPTY
};
void menu();
int main()
{
  int input = 0;
  Contact con ;
  InitContact(&con);
  do
  {
    menu();
    printf("请输入你想选择的操作:");
    scanf("%d", &input);
    switch (input)
    {
    case EXIT:
      printf("退出通讯录成功");
      break;
    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:
      SortContact(&con);
      break;
    case EMPTY:
      InitContact(&con);
      printf("清空通讯录成功\n");
      break;
    default:
      printf("输入错误\n");
      break;
    }
  } while (input);
  return 0;
}

contact.c

#include "contact.h"
void menu()
{
  printf("*****************************\n");
  printf("*****0.EXIT****1.ADD*********\n");
  printf("*****2.DEL*****3.SEARCH******\n");
  printf("*****4.MODIFY**5.SHOW********\n");
  printf("*****6.SORT****7.EMPTY*******\n");
}
void InitContact(Contact* pc)
{
  assert(pc);
  pc->sz = 0;
  memset(pc->data, 0, sizeof(pc->data));
}
void ADDContact(Contact* pc)
{
  assert(pc);
  if (pc->sz == MAX)
  {
    printf("通讯录已满,无法增加\n");
    return;
  }
  //增加信息
  printf("请输入姓名:");
  scanf("%s", pc->data[pc->sz].name);
  printf("请输入年龄:");
  scanf("%d", &(pc->data[pc->sz].age));
  printf("请输入性别:");
  scanf("%s", pc->data[pc->sz].sex);
  printf("请输入电话号码:");
  scanf("%s", pc->data[pc->sz].tele);
  printf("请输入住址:");
  scanf("%s", pc->data[pc->sz].addr);
  //
  pc->sz++;
  printf("添加联系人成功!\n");
}
void SHOWContact(const Contact* pc)
{
  assert(pc);
  if (pc->sz == 0)
  {
    printf("通讯录为空,无需打印\n");
    return;
  }
  int i = 0;
  //名字  年龄  性别  电话    地址
  //xxx   xxx  xxx  xxx     xxx
  printf("%-20s%-10s%-10s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址");
  for (i = 0; i < pc->sz; i++)
  {
    //打印每个人的信息
    printf("%-20s%-10d%-10s%-12s%-30s\n",
      pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);
  }
}
int FindByName(Contact* pc, char* name)
{
  assert(pc);
  int i = 0;
  for (i = 0; i < pc->sz; i++)
  {
    if (strcmp(pc->data[i].name,name)==0)
    {
      return i;
    }
  }
  return -1;
}
void DELContact(Contact* pc)
{
  char name[NAME_MAX];
  assert(pc);
  if (pc->sz == 0)
  {
    printf("通讯录为空,不可删除\n");
    return;
  }
  printf("请输入你想删除的联系人:");
  scanf("%s", name);
  int ret = FindByName(pc, name);
  if (ret == -1)
  {
    printf("该联系人不存在,无法删除!\n");
    return;
  }
  int i = 0;
  for (i = ret; i < pc->sz-1; i++)
  {
    pc->data[i] = pc->data[i + 1];
  }
  pc->sz--;
  printf("删除该联系人成功!\n");
}
void SearchContact(Contact* pc)
{
  assert(pc);
  char name[NAME_MAX];
  printf("请输入想查找的联系人");
  scanf("%s", &name);
  int ret = FindByName(pc, name);
  if (ret == -1)
  {
    printf("该联系人不存在!\n");
    return;
  }
  printf("%-20s%-10s%-10s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址");
  printf("%-20s%-10d%-10s%-12s%-30s\n",
    pc->data[ret].name, pc->data[ret].age, pc->data[ret].sex, pc->data[ret].tele, pc->data[ret].addr);
}
void ModifyContact(Contact* pc)
{
  assert(pc);
  char name[NAME_MAX];
  printf("请输入想修改的联系人");
  scanf("%s", &name);
  int ret = FindByName(pc, name);
  if (ret == -1)
  {
    printf("该联系人不存在!\n");
    return;
  }
  printf("请输入姓名:");
  scanf("%s", pc->data[ret].name);
  printf("请输入年龄:");
  scanf("%d", &(pc->data[ret].age));
  printf("请输入性别:");
  scanf("%s", pc->data[ret].sex);
  printf("请输入电话号码:");
  scanf("%s", pc->data[ret].tele);
  printf("请输入住址:");
  scanf("%s", pc->data[ret].addr);
  printf("修改联系人成功!\n");
}
int compare_name(const void* base,const void* src)
{
  return strcmp(((PeoInfo*)base)->name , ((PeoInfo*)src)->name);
}
int compare_age(const void* base, const void* src)
{
  return (((PeoInfo*)base)->age-((PeoInfo*)src)->age);
}
void SortContact(Contact* pc)
{
  int ret = 0;
  printf("1按名字排序,2按年龄排序\n");
  scanf("%d", &ret);
  if (ret == 1)
  {
      qsort(pc->data, pc->sz, sizeof(PeoInfo), compare_name);
      SHOWContact(pc);
      printf("名字排序成功\n");
  }
  else if (ret == 2)
  {
      qsort(pc->data, pc->sz, sizeof(PeoInfo), compare_age);
      SHOWContact(pc);
      printf("年龄排序成功\n");
  }
  else
  {
    printf("选择错误,返回操作");
  }
}

contact.h

#pragma once
#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<stdlib.h>
#define NAME_MAX 20
#define SEX_MAX 10
#define TELE_MAX 12
#define ADDR_MAX 30
#define MAX 100
typedef struct PeoInfo
{
  char name[NAME_MAX];
  int age;
  char sex[SEX_MAX];
  char tele[TELE_MAX];
  char addr[ADDR_MAX];
}PeoInfo;
typedef struct Contact
{
  PeoInfo data[MAX];//存放成员数据
  int sz;//记录当前通讯录人数
}Contact;
void menu();
void InitContact(Contact* pc);
void ADDContact(Contact* pc);
void SHOWContact(const Contact* pc);
void DELContact(Contact* pc);
void SearchContact(Contact* pc);
void ModifyContact(Contact* pc);
void SortContact(Contact* pc);

当然通讯录还有不完善的地方,以后会修改并带给大家,最后各位看客老爷万福金安。

目录
相关文章
|
运维 NoSQL Serverless
Serverless 应用引擎使用问题之首次启动无法获取redis连接,重启实例后可以获取,是什么原因
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
Serverless 应用引擎使用问题之首次启动无法获取redis连接,重启实例后可以获取,是什么原因
|
搜索推荐
这个知识点搞明白了,游戏开发中90%的数学问题就解决了
关键词:三角函数,游戏开发,游戏数学,微信小游戏制作工具,游戏开发教程。 嗨!大家好,我是小蚂蚁。 晓得上面那句话的逻辑谬误了吗?不论是学习数学,还是学习编程,都是锻炼一个人逻辑思维的方式,因为这两者对于思维的要求非常的严谨,稍有差池就会带来一个错误的结果。所以学习它们适合锻炼一个人严谨缜密的思维,你的逻辑思维是因为学习这两者而锻炼出来的,而不是要先要具备一定的逻辑思维,才能够进行学习。
327 0
|
SQL 开发框架 .NET
攻防世界---web---supersqli
攻防世界---web---supersqli
|
Java 关系型数据库 MySQL
【项目】手把手带你用 SpringBoot、Uniapp、MySql 开发一个简单的活动报名项目
【项目】手把手带你用 SpringBoot、Uniapp、MySql 开发一个简单的活动报名项目
845 1
|
XML Java 数据格式
优质全套Spring全套教程二
优质全套Spring全套教程二
123 0
|
云安全 存储 监控
《云上社交行业技术服务白皮书》——第三章 云上社交典型场景与架构——3.3 社交安全——3.3.2 云上数据信息安全(上)
《云上社交行业技术服务白皮书》——第三章 云上社交典型场景与架构——3.3 社交安全——3.3.2 云上数据信息安全(上)
425 0
|
Linux
常用Linux命令 - 目录和文件都能操作的命令
rm 是强大的删除命令,不仅可以删除文件,也可以删除目录。这个命令的基本信息如下。
150 0
|
网络安全 API 开发工具
【Python】【应用】Python应用之玩转gerrit系列之一——搭建基础环境
【Python】【应用】Python应用之玩转gerrit系列之一——搭建基础环境
1085 0
【Python】【应用】Python应用之玩转gerrit系列之一——搭建基础环境
|
数据安全/隐私保护 开发者
教辅系统的使用 | 学习笔记
快速学习教辅系统的使用,介绍了教辅系统的使用系统机制, 以及在实际应用过程中如何使用。
教辅系统的使用 | 学习笔记
|
存储 编译器
C · 进阶 | 联合体?看一遍就够了
结构体、枚举、联合体都是自定义类型
142 0
C · 进阶 | 联合体?看一遍就够了