C语言-史上最详细的通讯录

简介: C语言-史上最详细的通讯录

通讯录

文章目录

通讯录

前言

项目的文件划分

头文件的说明

准备工作

1.创建人类

2.创建通讯录

3.初始化通讯录

通讯录基本功能的实现

1.增加联系人

2.删除联系人

3.修改联系人

4.查找联系人

5.将联系人按照某种规则排序

6.显示通讯录中的联系人

7.通讯录菜单界面

8.菜单操作

通讯录代码

结束语

前言

学结构体学了这么久,终于要用结构体做点东西了。接下来就用结构体的知识实现一个简陋的通讯录。

项目的文件划分

和之前一样采用模块化的方式创建三个文件即可,一个测试文件text.c,一个contact.c为通讯录的具体实现以及contact.h用来存放实现contact.c的函数声明和类型。

头文件的说明

#pragma once
#include<stdio.h>
#include<string.h>
#include<assert.h>
#define MAX 1000
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_ADDER 30
#define MAX_TELE 15
//类型声明
enum Option
{
  EXIT,//0
  ADD,//1
  DELETE,//2
  SEARCH,//3
  MODIFY,//4
  SHOW,//5
  SORT//6
};
typedef struct PerInfo {
  int age;
  char name[MAX_NAME];
  char sex[MAX_SEX];
  char adder [MAX_ADDER];
  char tele[MAX_TELE];
}PerInfo;
typedef struct contact
{
  PerInfo data[MAX];
  int len;
}contact;
//函数声明
//初始化通讯录
void InitContact(contact* ps);
void AddContact(contact* ps);
void ShowContact(contact* ps);
void DeleteContact(contact *ps);
void SearchContact(contact *ps);
void ModifyContact(contact *ps);
void SortContact(contact* ps)

1.用define定义人的基本信息方便后期更改,这样定义可以做到一处修改与之相关的处处修改。

2.使用枚举实菜单中数字具有一定的意思,提高代码可读性。

准备工作

1.创建人类

首先通讯录本身可以看做是一个存放数据的容器,而里面的信息就是联系人的具体信息,既然我们要描述一个人的信息,如姓名,年龄,地址等,是用单一的内置类型是无法具体描述的,我们采用结构体这种复杂类型去描述人这个对象,第一步我们将创建一个用来描述人的结构体。

typedef struct PerInfo {
  int age;
  char name[MAX_NAME];
  char sex[MAX_SEX];
  char adder [MAX_ADDER];
  char tele[MAX_TELE];
}PerInfo;

2.创建通讯录

通讯录里面是不可能存放一个人的信息,它是要具备最基本的增删改查,本身也要具备一定的大小才能去存储信息。所以我们创建一个容量为1000PerInfo的数组的,当我们向里面加入一个人的信息时,我们需要知道通讯录的 容量是否已经达到最值,一旦达到便无法加入信息,由此可知,我们需要一个变量去统计通讯录中的人数。此时我们如果进行增删改查,我们传参的时候即要传联系人的信息和人数,为了减少传参的个数,我们可以将联系人和人数一起放到一个结构体中。该结构体就定义为通讯录。

typedef struct contact
{
  PerInfo data[MAX];
  int len;
}contact;

3.初始化通讯录

当我们创建好通讯录后需要对通讯录中的数组和变量进行初始化,如果不初始化的话,里面的值都是系统生成的随机值,是无意义的。所以我们将通讯录中的数据都初始化为0,并将这个功能单独定义成一个函数。

void InitContact(contact* ps)
{
  ps->len = 0;
  memset(ps->data,0,sizeof(ps->data));
}

此时一个空白的数据就创建好了。

通讯录基本功能的实现

1.增加联系人

首先我们要判断通讯录中是否已满,如果已满自然不能加入联系人。如果未满,则添加联系人。我们初始化的时候数组和人数都是0,我们不妨将人数len当做数组的下标来操作,当联系人的信息成功添加len则++。

void AddContact(contact* ps)
{
  if (ps->len == MAX)
  {
    printf("通讯录已满,无法添加");
    return;
  }
    printf("请输入您要xxx的基本信息:\n");
    printf("请输入姓名:");
    scanf("%s", ps->data[ps->len].name);
    printf("请输入年龄:");
    scanf("%d", &(ps->data[ps->len].age));
    printf("请输入性别:");
    scanf("%s", ps->data[ps->len].sex);
    printf("请输入手机号码:");
    scanf("%s", ps->data[ps->len].tele);
    printf("请输入住址:");
    scanf("%s", ps->data[ps->len].adder);
    ps->len++;
    printf("添加成功!\n");
}

2.删除联系人

我们先要先判断通讯录是否为空,为空无法删,否则就删。我们删除的前提是要找到某个联系人,就像我们在微信上拉黑某人的去列表中找他在删他。所以我们现在通讯录不为空的前提下查找某一联系人的姓名,当我们找到的时候就删了它。又因为这个查找联系人的功能我们在后面的功能里面也会使用,所以也将它封装成一个函数,以便后面使用。

int isByName(contact *ps,char  name[])
{
  for (int i = 0; i < ps->len; i++)
  {
    if (0 == strcmp(ps->data[i].name, name))
    {
      return 1;
    }
  }
  return -1;
}
void DeleteContact(contact *ps)
{
  assert(ps);
  char name[20] = { 0 };
  printf("请输入您要删除的联系人的名字:");
  scanf("%s", name);
  int ret=isByName(ps, name);
  if (ps->len >= 0)
  {
    printf("通讯录为空,无法删除\n");
    return;
  }
  if (ret == -1)
  {
    printf("查无此人");
  }
  else 
  {
    for (int i = 0; i < ps->len - 1; i++)
    {
      ps->data[i] = ps->data[i + 1];
    }
    ps->len--;
    printf("删除成功!\n");
  }
}

3.修改联系人

修改联系人和删除联系人的逻辑基本一致,也是先找后操作。我们采用的是传址调用。所以我们找到人之后再重新说输入一遍新联系人的信息便能更改。

void ModifyContact(contact* ps)
{
  assert(ps);
  char name[20] = { 0 };
  printf("请输入您要修改的联系人的名字:");
  scanf("%s", name);
  int pos = isByName(ps, name);
  if (pos == -1)
  {
    printf("查无此人");
  }
  else
  {
    printf("请输入姓名:");
    scanf("%s", ps->data[pos].name);
    printf("请输入年龄:");
    scanf("%d", &(ps->data[pos].age));
    printf("请输入性别:");
    scanf("%s", ps->data[pos].sex);
    printf("请输入手机号码:");
    scanf("%s", ps->data[pos].tele);
    printf("请输入住址:");
    scanf("%s", ps->data[pos].adder);
    printf("添加修改!\n");
  }
}

4.查找联系人

查找就是在通讯录中去找,找到了将打印该联系人的信息,没有找到则打印查无此人。

void SearchContact(contact* ps)
{
  assert(ps);
  char name[20] = { 0 };
  printf("请输入您要查找的联系人的名字:");
  scanf("%s", name);
  int pos = isByName(ps, name);
  if (pos == -1)
  {
    printf("查无此人");
  }
  else
  {
    printf("%-20s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "手机号码", "地址");
    printf("%-20s %-5d %-5s %-12s %-30s\n", ps->data[pos].name, ps->data[pos].age
      , ps->data[pos].sex, ps->data[pos].tele, ps->data[ps].adder);
  }
}

5.将联系人按照某种规则排序

我们这里采用的是根据姓名进行排序,也可以按照年龄只需要更改比较规则即可。

int ComparyByName(const void* e1, const void* e2)
{
  return strcmp((const char*)e1, (const char*)e2);
}
void SortContact(contact* ps) 
{
  qsort(ps->data, ps->len, sizeof(PerInfo), ComparyByName);
}

6.显示通讯录中的联系人

只需要将通讯录中信息打印出来即可。

void ShowContact(contact* ps)
{
  assert(ps);
  printf("%-20s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "手机号码", "地址");
  for (int i = 0; i < ps->len; i++)
  {
    printf("%-20s %-5d %-5s %-12s %-30s\n", ps->data[i].name, ps->data[i].age
      , ps->data[i].sex, ps->data[i].tele, ps->data[i].adder);
  }
}

通讯录基本的功能实现了,为了界面友好与操作,就为通讯录整个菜单。

7.通讯录菜单界面

void menu()
{
  printf("**|******************|**\n");
  printf("**|1.Add  2.Delete***|**\n");
  printf("**|3.Seacher 4.Modify|**\n");
  printf("**   |5.Show 6.Sort|  **\n");
  printf("**      |0.Exit|      **\n");
  printf("**********|***|*********\n");
  printf("************|***********\n");
}

我们将菜单具体实现也就是操作通讯录的过程也封装成一个函数。

8.菜单操作

void text()
{
  int input = 0;
  contact con;
  InitContact(&con);
  do {
    menu();
    printf("请输入您的选择:");
    scanf("%d", &input);
    switch (input)
    {
    case ADD:
      AddContact(&con);
      break;
    case DELETE:
      DeleteContact(&con);
      break;
    case SEARCH:
      SearchContact(&con);
      break;
    case MODIFY:
      ModifyContact(&con);
      break;
    case SHOW:
      ShowContact(&con);    
      break;
    case SORT:
      SortContact(&con);
      break;
    case EXIT:
      printf("退出通讯录");
      break;
    default:
      printf("您的选择有误,请重新输入!");
    }
  } while (input);
}

通讯录代码

//contact.h文件用于声明函数和类型
#pragma once
#include<stdio.h>
#include<string.h>
#include<assert.h>
#define MAX 1000
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_ADDER 30
#define MAX_TELE 15
//类型声明
enum Option
{
  EXIT,//0
  ADD,//1
  DELETE,//2
  SEARCH,//3
  MODIFY,//4
  SHOW,//5
  SORT//6
};
typedef struct PerInfo {
  int age;
  char name[MAX_NAME];
  char sex[MAX_SEX];
  char adder [MAX_ADDER];
  char tele[MAX_TELE];
}PerInfo;
typedef struct contact
{
  PerInfo data[MAX];
  int len;
}contact;
//函数声明
//初始化通讯录
void InitContact(contact* ps);
void AddContact(contact* ps);
void ShowContact(contact* ps);
void DeleteContact(contact *ps);
void SearchContact(contact *ps);
void ModifyContact(contact *ps);
void SortContact(contact* ps);
//contact.c文件 通讯录功能的具体实现
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
void InitContact(contact* ps)
{
  ps->len = 0;
  memset(ps->data,0,sizeof(ps->data));
}
void AddContact(contact* ps)
{
  if (ps->len == MAX)
  {
    printf("通讯录已满,无法添加");
    return;
  }
    printf("请输入您要xxx的基本信息:\n");
    printf("请输入姓名:");
    scanf("%s", ps->data[ps->len].name);
    printf("请输入年龄:");
    scanf("%d", &(ps->data[ps->len].age));
    printf("请输入性别:");
    scanf("%s", ps->data[ps->len].sex);
    printf("请输入手机号码:");
    scanf("%s", ps->data[ps->len].tele);
    printf("请输入住址:");
    scanf("%s", ps->data[ps->len].adder);
    ps->len++;
    printf("添加成功!\n");
}
void ShowContact(contact* ps)
{
  assert(ps);
  printf("%-20s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "手机号码", "地址");
  for (int i = 0; i < ps->len; i++)
  {
    printf("%-20s %-5d %-5s %-12s %-30s\n", ps->data[i].name, ps->data[i].age
      , ps->data[i].sex, ps->data[i].tele, ps->data[i].adder);
  }
}
int isByName(contact *ps,char  name[])
{
  for (int i = 0; i < ps->len; i++)
  {
    if (0 == strcmp(ps->data[i].name, name))
    {
      return 1;
    }
  }
  return -1;
}
void DeleteContact(contact *ps)
{
  assert(ps);
  char name[20] = { 0 };
  printf("请输入您要删除的联系人的名字:");
  scanf("%s", name);
  int ret=isByName(ps, name);
  if (ps->len >= 0)
  {
    printf("通讯录为空,无法删除\n");
    return;
  }
  if (ret == -1)
  {
    printf("查无此人");
  }
  else 
  {
    for (int i = 0; i < ps->len - 1; i++)
    {
      ps->data[i] = ps->data[i + 1];
    }
    ps->len--;
    printf("删除成功!\n");
  }
}
void SearchContact(contact* ps)
{
  assert(ps);
  char name[20] = { 0 };
  printf("请输入您要查找的联系人的名字:");
  scanf("%s", name);
  int pos = isByName(ps, name);
  if (pos == -1)
  {
    printf("查无此人");
  }
  else
  {
    printf("%-20s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "手机号码", "地址");
    printf("%-20s %-5d %-5s %-12s %-30s\n", ps->data[pos].name, ps->data[pos].age
      , ps->data[pos].sex, ps->data[pos].tele, ps->data[pos].adder);
  }
}
void ModifyContact(contact* ps)
{
  assert(ps);
  char name[20] = { 0 };
  printf("请输入您要修改的联系人的名字:");
  scanf("%s", name);
  int pos = isByName(ps, name);
  if (pos == -1)
  {
    printf("查无此人");
  }
  else
  {
    printf("请输入姓名:");
    scanf("%s", ps->data[pos].name);
    printf("请输入年龄:");
    scanf("%d", &(ps->data[pos].age));
    printf("请输入性别:");
    scanf("%s", ps->data[pos].sex);
    printf("请输入手机号码:");
    scanf("%s", ps->data[pos].tele);
    printf("请输入住址:");
    scanf("%s", ps->data[pos].adder);
    printf("添加修改!\n");
  }
}
int ComparyByName(const void* e1, const void* e2)
{
  return strcmp((const char*)e1, (const char*)e2);
}
void SortContact(contact* ps) 
{
  qsort(ps->data, ps->len, sizeof(PerInfo), ComparyByName);
}
//text.c文件 通讯录的启动
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include "contact.h"
void menu()
{
  printf("**|******************|**\n");
  printf("**|1.Add  2.Delete***|**\n");
  printf("**|3.Seacher 4.Modify|**\n");
  printf("**   |5.Show 6.Sort|  **\n");
  printf("**      |0.Exit|      **\n");
  printf("**********|***|*********\n");
  printf("************|***********\n");
}
void text()
{
  int input = 0;
  contact con;
  InitContact(&con);
  do {
    menu();
    printf("请输入您的选择:");
    scanf("%d", &input);
    switch (input)
    {
    case ADD:
      AddContact(&con);
      break;
    case DELETE:
      DeleteContact(&con);
      break;
    case SEARCH:
      SearchContact(&con);
      break;
    case MODIFY:
      ModifyContact(&con);
      break;
    case SHOW:
      ShowContact(&con);    
      break;
    case SORT:
      SortContact(&con);
      break;
    case EXIT:
      printf("退出通讯录");
      break;
    default:
      printf("您的选择有误,请重新输入!");
    }
  } while (input);
}
int main() 
{
  text();
  return 0;
}
结束语

以上就是本次分享,希望对大家有帮助吧~。如果看完,跪求三连。

相关文章
|
6天前
|
C语言
用c语言实现一个通讯录
用c语言实现一个通讯录
12 0
|
6天前
|
存储 C语言
C语言详解【通讯录的实现】
C语言详解【通讯录的实现】
|
6天前
|
存储 XML JSON
【C语言-通讯录的分析与实现】
我们以手机里面的通讯录为例,说明通讯录主要有以下什么功能,我们先用一张简单的图来说明一下
24 0
|
1天前
|
存储 编译器 C语言
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose(下)
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose
8 0
|
1天前
|
C语言
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose(中)
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose
8 0
|
1天前
|
存储 数据库 C语言
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose(上)
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose
8 0
|
1天前
|
程序员 编译器 C语言
C语言进阶⑰(动态内存管理)四个动态内存函数+动态通讯录+柔性数组_malloc+free(下)
C语言进阶⑰(动态内存管理)四个动态内存函数+动态通讯录+柔性数组_malloc+free
5 0
C语言进阶⑰(动态内存管理)四个动态内存函数+动态通讯录+柔性数组_malloc+free(下)
|
1天前
|
C语言 C++
C语言进阶⑰(动态内存管理)四个动态内存函数+动态通讯录+柔性数组_malloc+free(中)
C语言进阶⑰(动态内存管理)四个动态内存函数+动态通讯录+柔性数组_malloc+free
9 0
|
1天前
|
编译器 数据库 C语言
C语言进阶⑰(动态内存管理)四个动态内存函数+动态通讯录+柔性数组_malloc+free(上)
C语言进阶⑰(动态内存管理)四个动态内存函数+动态通讯录+柔性数组_malloc+free
9 0
C语言进阶⑰(动态内存管理)四个动态内存函数+动态通讯录+柔性数组_malloc+free(上)
|
1天前
|
编译器 C语言
C语言进阶⑯(自定义类型)项目:静态通讯录,增删查改排序打印。
C语言进阶⑯(自定义类型)项目:静态通讯录,增删查改排序打印。
12 1