利用结构体实现通讯录

在学习完结构体知识后,我们就来一起写一个通讯录。

首先明确内容,我们要弄清楚我们要构建的通讯录可以保存1000的人的信息,其次通讯录要能增加联系人,删除联系人,同时要实现对联系人的修改,查找和排序,接着便是开始编写我们的代码

首先创建一个工程contact.h来存放所有的头文件,用结构体来编写我们要存放的内容

typedef struct PeoInfo
{
 char name[NAME_MAX];
 short age;
 char sex[SEX_MAX];
 char tele[TELE_MAX];
 char addr[ADDR_MAX];
}PeoInfo;

利用宏定义定义数组的大小来方便我们后期进行更改,利用typedef来方便我们引用结构体定义,定义好后,我们就来实现主函数的实现,创建工程test.c来实现工程

#include "Contact.h"
​
void menu()
{
 printf("******************************\n");
 printf("** 1. add   2. del **\n");
 printf("** 3. search 4. modify **\n");
 printf("** 5. show  6. clear **\n");
 printf("** 7. sort  0. exit **\n");
 printf("******************************\n");
}
​
int main()
{
 int input = 0;
 //创建通讯录
 Contact con;//
 //初始化通讯录
 InitContact(&con);
 do 
 {
  menu();
  printf("请选择:>");
  scanf("%d", &input);
  switch(input)
  {
  case ADD:
   AddContact(&con);
   break;
  case DEL:
   DelContact(&con);
   break;
    case SEARCH:
      FindContact(&con);
   break;
  case SORT:
      SortContact(&con);
   break;
  case MODIFY:
      ModifyContact(&con);
   break;
  case SHOW:
   ShowContact(&con);
   break;
  case CLEAR:
      ClearContact(&con);
      break;
  case EXIT:
   printf("退出程序\n");
   return 0;
  default:
   printf("输入有误,请重新输入\n");
   break;
  }
 } while (input);
 return 0;
}

现将之前创建的头文件应用,接着利用Switch语句来实现选择的功能并在其中插入我们要实现的函数功能,利用指针来访问结构体

然后我们在将所要实现的函数放入头文件中,代码如下

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <errno.h>
​
enum Option
{
 EXIT,
 ADD,
 DEL,
 SEARCH,
 MODIFY,
 SHOW,
  CLEAR,
 SORT
};
​
#define DEFAULT_SZ 3
#define MAX 1000
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 25
​
//人的信息
typedef struct PeoInfo
{
 char name[NAME_MAX];
 short age;
 char sex[SEX_MAX];
 char tele[TELE_MAX];
 char addr[ADDR_MAX];
}PeoInfo;
​
//通讯录结构体
​
typedef struct Contact
{
 PeoInfo data[MAX];//存放真实数据的空间
 int sz;//记录有效数据的个数
}Contact;
​
void InitContact(Contact* pcon);
void AddContact(Contact* pcon);
void DelContact(Contact* pcon);
void FindContact(Contact* pcon);
void ModifyContact(Contact* pcon);
void ShowContact(const Contact* pcon);
void ClearContact(Contact* pcon);
void SortContact(Contact* pcon);

再次构建结构体是为了方便向通讯录中录入信息。然后我们便来一一实现这些函数

优化部分:我们此处实现的仅仅是可以添加1000个联系人的信息,如果只加三个人的信息,则会浪费空间,如增加的人多,则无法实现,所以我们可以利用动态存储函数来扩容。

首先要修改结构体声明部分:

typedef struct Contact
{
   Struct peoInform *data;
   int size;
   int capacity;//当前通讯录已经有的元素个数
}Contact;

1.初始化结构体信息

void InitContact(Contact* pcon) 
{
 assert(pcon);
 pcon->sz = 0;
 memset(pcon->data, 0, sizeof(pcon->data));
}

定义一个函数来初始化通讯录的内容,之后有其他功能进行复制,利用memset函数来实现元素初始化

优化:

在使用动态内存函数后,初始化函数也需要优化:

void InitContact(Contact *pcon)
{
  ps->data=(Struct PeoInform*)malloc(Space*sizeof(Struct PeoInform))
  if(ps->data=NULL)
  {
    return;
  }
  pc->size=0;
  ps->capacity = Space;
}

2.增加联系人函数

void AddContact(Contact* pcon)
{
 assert(pcon);
 if(pcon->sz == pcon->capacity)
 {
   PeoInfo* tmp=(PeoInfo*)realloc(pcon->data,(pcon->capactity+2)*sizeof(PeoInfo));
   if(tmp== NULL)
    {
      pcon->data=tmp;
    }
   pc->capacity+=2;
 }
 //录入信息
 printf("请输入名字:>");
 scanf("%s", pcon->data[pcon->sz].name);
 printf("请输入年龄:>");
 scanf("%d", &(pcon->data[pcon->sz].age));
 printf("请输入性别:>");
 scanf("%s", pcon->data[pcon->sz].sex);
 printf("请输入电话:>");
 scanf("%s", pcon->data[pcon->sz].tele);
 printf("请输入地址:>");
 scanf("%s", pcon->data[pcon->sz].addr);
​
 pcon->sz++;
 printf("增加成功\n");
}

该函数较为简单,但要注意的是每增加一个联系人信息,便要将sz加1来记录总人数

3.查找人名函数

static int FindByName(Contact* pcon, char name[])
{
 int i = 0;
 assert(pcon);
 for(i=0; i<pcon->sz; i++)
 {
  if(0 == strcmp(pcon->data[i].name, name))
  {
   return i;
  }
 }
 //找不到
 return -1;
}
​

为查找名字,要将名字数组传到函数中去,利用strcmp函数比较字符串,通过遍历来查找人名。

3.删除联系人信息函数

void DelContact(Contact* pcon)
{
 int i = 0;
 char name[NAME_MAX] = {0};
 int pos = 0;
 assert(pcon);
 
 if(pcon->sz == 0) //空的就不用删了
 {
  printf("通讯录已空,无法删除\n");
  return;
 }
 //删除
 printf("请输入要删除人的名字:>");
 scanf("%s", name);
 //查找(删除之前需要先查找)
 pos = FindByName(pcon, name);
 if(pos == -1)
 {
  printf("要删除的条目不存在\n");
  return;
 }
 //移除
 for(i=pos; i<pcon->sz; i++)
 {
  pcon->data[i] = pcon->data[i+1];
 }
 pcon->sz--;
 printf("删除成功\n");
}
​

首先要注意要用到前面的查找函数,如果找到此联系人信息用后一个联系人信息覆盖掉,同时将sz减去1重新记录联系人人数

5.修改联系人信息

void ModifyContact(Contact* pcon)
{
 int i = 0;
 char name[NAME_MAX] = {0};
 int pos = 0;
 assert(pcon);
 
 if(pcon->sz == 0) //空的就不用找
 {
  printf("通讯录已空,无法修改信息\n");
  return;
 }
 //修改
 printf("请输入要修改条目的姓名:>");
 scanf("%s", name);
 //查找(修改之前需要先查找)
 pos = FindByName(pcon, name);
 if(pos == -1)
 {
  printf("要修改的条目不存在\n");
  return;
 }
 //询问要改什么
  printf("请输入要修改什么信息(1-名字,2-年龄,3-性别,4-电话,5-住址):>");
  int msg;
  scanf("%d", &msg);
  switch(msg)
 {
    case 1:
      printf("请输入新的姓名:>");
      scanf("%s", pcon->data[pos].name);
      break;
    case 2:
      printf("请输入新的年龄:>");
      scanf("%d", &pcon->data[pos].age);
      break;
    case 3:
      printf("请输入新的性别:>");
      scanf("%s", pcon->data[pos].sex);
      break;
    case 4:
      printf("请输入新的电话:>");
      scanf("%s", pcon->data[pos].tele);
      break;
    case 5:
      printf("请输入新的地址:>");
      scanf("%s", pcon->data[pos].addr);
      break;
    default:
      printf("输入有误,修改失败\n");
      return;
 }
 printf("修改成功\n");
}
​

首先判别通讯录中是否有联系人,其次便将需要修改的联系人的信息重新复制。

6.展示所有联系人信息

void ShowContact(const Contact* pcon)
{
 int i = 0;
 assert(pcon);
 printf("%15s\t%5s\t%5s\t%12s\t%20s\n", "名字", "年龄", "性别", "电话", "地址");
 for(i=0; i<pcon->sz; i++)
 {
  printf("%15s\t%5d\t%5s\t%12s\t%20s\n", pcon->data[i].name, 
   pcon->data[i].age, 
   pcon->data[i].sex,
   pcon->data[i].tele,
   pcon->data[i].addr);
 }
}

此函数相较前几种简单,利用遍历即可将所有联系人信息打印出来

7.销毁通讯录

因为我们做出了利用动态内存函数的改进,所以我们应该记得释放开辟的空间防止发生错误

代码如下:
 

void destorContact(Contact* pcon)
{
  free(pc->data);
  pc->data = NULL:
  pc->capacity=0;
  pc->sz=0;
  printf("销毁成功");
}

完整函数如下:

contact.h:

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <errno.h>
​
enum Option
{
 EXIT,
 ADD,
 DEL,
 SEARCH,
 MODIFY,
 SHOW,
  CLEAR,
 SORT
};
​
#define DEFAULT_SZ 3
#define MAX 1000
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 25
​
//人的信息
typedef struct PeoInfo
{
 char name[NAME_MAX];
 short age;
 char sex[SEX_MAX];
 char tele[TELE_MAX];
 char addr[ADDR_MAX];
}PeoInfo;
​
//通讯录结构体
​
typedef struct Contact
{
 PeoInfo data[MAX];//存放真实数据的空间
 int sz;//记录有效数据的个数
}Contact;
​
void InitContact(Contact* pcon);
void AddContact(Contact* pcon);
void DelContact(Contact* pcon);
void FindContact(Contact* pcon);
void ModifyContact(Contact* pcon);
void ShowContact(const Contact* pcon);
void ClearContact(Contact* pcon);
void SortContact(Contact* pcon);
contact.c:

#include "Contact.h"
​
//初始化通讯录
void InitContact(Contact* pcon) 
{
 assert(pcon);
 pcon->sz = 0;
 memset(pcon->data, 0, sizeof(pcon->data));
}
​
//1、添加联系人信息
void AddContact(Contact* pcon)
{
 assert(pcon);
 
 //录入信息
 printf("请输入名字:>");
 scanf("%s", pcon->data[pcon->sz].name);
 printf("请输入年龄:>");
 scanf("%d", &(pcon->data[pcon->sz].age));
 printf("请输入性别:>");
 scanf("%s", pcon->data[pcon->sz].sex);
 printf("请输入电话:>");
 scanf("%s", pcon->data[pcon->sz].tele);
 printf("请输入地址:>");
 scanf("%s", pcon->data[pcon->sz].addr);
​
 pcon->sz++;
 printf("增加成功\n");
}
​
//查找指定条目下标
static int FindByName(Contact* pcon, char name[])
{
 int i = 0;
 assert(pcon);
 for(i=0; i<pcon->sz; i++)
 {
  if(0 == strcmp(pcon->data[i].name, name))
  {
   return i;
  }
 }
 //找不到
 return -1;
}
​
//2、删除指定联系人信息
void DelContact(Contact* pcon)
{
 int i = 0;
 char name[NAME_MAX] = {0};
 int pos = 0;
 assert(pcon);
 
 if(pcon->sz == 0) //空的就不用删了
 {
  printf("通讯录已空,无法删除\n");
  return;
 }
 //删除
 printf("请输入要删除人的名字:>");
 scanf("%s", name);
 //查找(删除之前需要先查找)
 pos = FindByName(pcon, name);
 if(pos == -1)
 {
  printf("要删除的条目不存在\n");
  return;
 }
 //移除
 for(i=pos; i<pcon->sz; i++)
 {
  pcon->data[i] = pcon->data[i+1];
 }
 pcon->sz--;
 printf("删除成功\n");
}
​
//3、查找指定联系人信息
void FindContact(Contact* pcon)
{
 int i = 0;
 char name[NAME_MAX] = {0};
 int pos = 0;
 assert(pcon);
 
 if(pcon->sz == 0) //空的就不用删了
 {
  printf("通讯录已空,无法查找\n");
  return;
 }
​
  //查找
 printf("请输入要查找人的名字:>");
 scanf("%s", name);
​
 pos = FindByName(pcon, name);
 if(pos == -1)
 {
  printf("要查找的条目不存在\n");
  return;
 }
 
  printf("%15s\t%5d\t%5s\t%12s\t%20s\n", pcon->data[pos].name, 
   pcon->data[pos].age, 
   pcon->data[pos].sex,
   pcon->data[pos].tele,
   pcon->data[pos].addr);
}
​
//4、修改指定联系人信息
void ModifyContact(Contact* pcon)
{
 int i = 0;
 char name[NAME_MAX] = {0};
 int pos = 0;
 assert(pcon);
 
 if(pcon->sz == 0) //空的就不用找
 {
  printf("通讯录已空,无法修改信息\n");
  return;
 }
 //修改
 printf("请输入要修改条目的姓名:>");
 scanf("%s", name);
 //查找(修改之前需要先查找)
 pos = FindByName(pcon, name);
 if(pos == -1)
 {
  printf("要修改的条目不存在\n");
  return;
 }
 //询问要改什么
  printf("请输入要修改什么信息(1-名字,2-年龄,3-性别,4-电话,5-住址):>");
  int msg;
  scanf("%d", &msg);
  switch(msg)
 {
    case 1:
      printf("请输入新的姓名:>");
      scanf("%s", pcon->data[pos].name);
      break;
    case 2:
      printf("请输入新的年龄:>");
      scanf("%d", &pcon->data[pos].age);
      break;
    case 3:
      printf("请输入新的性别:>");
      scanf("%s", pcon->data[pos].sex);
      break;
    case 4:
      printf("请输入新的电话:>");
      scanf("%s", pcon->data[pos].tele);
      break;
    case 5:
      printf("请输入新的地址:>");
      scanf("%s", pcon->data[pos].addr);
      break;
    default:
      printf("输入有误,修改失败\n");
      return;
 }
 printf("修改成功\n");
}
​
//5、显示所有联系人信息
void ShowContact(const Contact* pcon)
{
 int i = 0;
 assert(pcon);
 printf("%15s\t%5s\t%5s\t%12s\t%20s\n", "名字", "年龄", "性别", "电话", "地址");
 for(i=0; i<pcon->sz; i++)
 {
  printf("%15s\t%5d\t%5s\t%12s\t%20s\n", pcon->data[i].name, 
   pcon->data[i].age, 
   pcon->data[i].sex,
   pcon->data[i].tele,
   pcon->data[i].addr);
 }
}
​
//6、清空所有联系人信息
void ClearContact(Contact* pcon)
{
  InitContact(pcon);
}
​
//7、按照名字排序
void SortContact(Contact* pcon)
{
  int i, j;
  PeoInfo tmp;
  for(i = 0; i < pcon->sz - 1; i++)
 {
    for(j = 0; j < pcon->sz - 1 - i; j++)
   {
      if(0 < strcmp(pcon->data[j].name, pcon->data[j + 1].name))
     {
        tmp = pcon->data[j];
        pcon->data[j] = pcon->data[j + 1];
        pcon->data[j + 1] = tmp;
     }
   }
 }
}
测试代码:

#include "Contact.h"
​
void menu()
{
 printf("******************************\n");
 printf("** 1. add   2. del **\n");
 printf("** 3. search 4. modify **\n");
 printf("** 5. show  6. clear **\n");
 printf("** 7. sort  0. exit **\n");
 printf("******************************\n");
}
​
int main()
{
 int input = 0;
 //创建通讯录
 Contact con;//
 //初始化通讯录
 InitContact(&con);
 do 
 {
  menu();
  printf("请选择:>");
  scanf("%d", &input);
  switch(input)
  {
  case ADD:
   AddContact(&con);
   break;
  case DEL:
   DelContact(&con);
   break;
    case SEARCH:
      FindContact(&con);
   break;
  case SORT:
      SortContact(&con);
   break;
  case MODIFY:
      ModifyContact(&con);
   break;
  case SHOW:
   ShowContact(&con);
   break;
  case CLEAR:
      ClearContact(&con);
      break;
  case EXIT:
   printf("退出程序\n");
   return 0;
  default:
   printf("输入有误,请重新输入\n");
   break;
  }
 } while (input);
 return 0;
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

抱着太阳吃雪糕z

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

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

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

打赏作者

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

抵扣说明:

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

余额充值