C语言进阶第八课 --------通讯录的实现

简介: C语言进阶第八课 --------通讯录的实现

通讯录的结构

我们要写一个通讯录首先要知道具体架构


  1. 可以保存100个人的信息
  2. 删除指定联系人的信息
  3. 查找指定联系人的信息
  4. 修改指定联系人的信息
  5. 排序通讯录的信息


我们还要知道联系人的信息有哪里


  1. 名字
  2. 年龄
  3. 性别
  4. 电话
  5. 住址

现在我们大概清楚了通讯录的大致架构下面我们一一解决


通讯录的各各方向

通讯录的大致架构

#include "通讯录声明.h"
int main()
{
  int input = 0;;
  printf("是否开始通讯录的操作(0(否)/1(是)):>");
  scanf("%d",&input);
  switch (input)
  {
  case 0:
    printf("欢迎下次光临,大佬慢走\n");
    break;
  case 1:
    while (1)
    {
      int select;
      emun();
      printf("你要进行的行为是:>");
      scanf("%d", &select);
      switch (select)
      {
      case 0://结束
        break;
      case 1://增
        break;
      case 2://删
        break;
      case 3://查
        break;
      case 4://修改
        break;
      case 5://排序
        break;
      case 6://显示
        break;
      default:
        printf("你的操作有误,请重新操作\n");
        break;
      }
      if (select == 0)
        break;
    }
    printf("操作完成,请慢走\n");
    break;
  default:
    printf("输入错误,请重新输入\n");
  }
  return 0;
}

或者是这种

#include "通讯录声明.h"
enum Operate
{
  EXIT,
  ADD,
  DEL,
  SEEK,
  MODIFY,
  SORT,
  SHOW,
  

};
int main()
{
  int input = 0;
  printf("是否开始通讯录的操作(0(否)/1(是)):>");
  scanf("%d", &input);
  do
  {
    if (input != 0 && input != 1)
    {
      printf("输入错误,请重新输入\n");
      printf("是否开始通讯录的操作(0(否)/1(是)):>");
      scanf("%d", &input);
      continue;
    }
    int select;
    emun();
    printf("你要进行的行为是:>");
    scanf("%d", &select);
    switch (select)
    {
    case EXIT://结束
      break;
    case ADD://增
      break;
    case DEL://删
      break;
    case SEEK://查
      break;
    case MODIFY://修改
      break;
    case SORT://排序
      break;
    case SHOW://显示
      break;
    default:
      printf("你的操作有误,请重新操作\n");
      break;
    }
    if (select == 0)
    {
      break;
    }
  } while (input);
  printf("退出成功,欢迎下次光临,大佬慢走\n");
  return 0;
}

我以第二种架构为例

菜单

void emun()
{
  printf("********************************\n");
  printf("******  0.Exit     1.Add  ******\n");
  printf("******  2.Del      3.Seek ******\n");
  printf("******  4.modify   5.sort ******\n");
  printf("******      6.short       ******\n");
  printf("********************************\n");
}

人的信息和通讯录

//人的信息
struct People
{
  char name[NAME];
  int age;
  char sex[SEX];
  char phone[PHONE];
  char address[ADDRESS];

};
//封装成通讯录的样子
struct address_book
{
  struct People peple_address_num[PEPLE_ADDRESS_NUM]; //人的信息集合
  int conut; //统计人数
};

结构体变量初始化

void initialization(struct address_book* table)
{
  assert(table);
  (*table).conut = 0;
  //peple_address_num数组的初始化 ---方法1
  int sz = sizeof(struct People) * PEPLE_ADDRESS_NUM;
  memset(table->peple_address_num, 0, sz);
  //peple_address_num数组的初始化 ---方法2
  /*int i = 0;
  for (i = 0; i < ADDRESS; i++)
  {
    (*table).peple_address_num[i].age = 0;
    int j = 0;
    for (j = 0; j < NAME; j++)
    {
      (*table).peple_address_num[i].name[j] = 0;
    }
    for (j = 0; j < SEX; j++)
    {
      (*table).peple_address_num[i].sex[j] = 0;
    }
    for (j = 0; j < PHONE; j++)
    {
      (*table).peple_address_num[i].phone[j] = 0;
    }
    for (j = 0; j < ADDRESS; j++)
    {
      (*table).peple_address_num[i].address[j] = 0;
    }
    
  }*/
}

增加成员

void Add_address(struct address_book* table)
{
  assert(table);
  //判断count的大小
  if (table->conut == PEPLE_ADDRESS_NUM)
  {
    printf("通讯录已经满了");
    return;
  }
  getchar();
  printf("输入名字:");
  gets(table->peple_address_num[table->conut].name);
  printf("输入年龄:");
  scanf("%d", &(table->peple_address_num[table->conut].age));
  getchar();
  printf("输入性别:");
  gets(table->peple_address_num[table->conut].sex);
  printf("输入电话号码:");
  gets(table->peple_address_num[table->conut].phone);
  printf("输入地址");
  gets(table->peple_address_num[table->conut].address);
}

显示

void Show_address(const struct address_book* table)
{
  assert(table);
  if (table->conut == 0)
  {
    printf("内容为空,无需打印\n");
    return;
  }
  int i = 0;
  printf("显示如下:\n");
  printf("%-20s %-5s %-5s %-12s %-100s\n", "名字", "年龄", "性别", "电话", "地址");
  for (i = 0; i < table->conut; i++)
  {
    printf("%-20s ", table->peple_address_num[i].name);
    printf("%-5d ", table->peple_address_num[i].age);
    printf("%-5s ", table->peple_address_num[i].sex);
    printf("%-12s ", table->peple_address_num[i].phone);
    printf("%-100s\n", table->peple_address_num[i].address);
  }
}

删除

void Del_adderss( struct address_book * table)
{
  assert(table);
  //判断通讯录是否为空
  if (table->conut == 0)
  {
    printf("通讯录为空\n");
    return;
  }
  //开始删除
  printf("你要删除人的名字是:");
  char arr[NAME];
  scanf("%s", arr);
  int idx = Seek_adderss(table, arr);
  if ( idx != -1)
  {
    //进行删除
    table->conut--;
    
    while (idx < table->conut)
    {
      table->peple_address_num[idx] = table->peple_address_num[idx + 1];
      idx++;
    }
    printf("删除成功\n");
  }
  else
    printf("无这个人\n");
  



}

查找

int Seek_adderss(struct address_book* table, char * arr)
{
  assert(arr && table);
  int i = 0;
  for (i = 0; i < table->conut; i++)
  {
    if (strcmp((char*)(&(table->peple_address_num[i])), arr) == 0)
    {
      return i;
    }
  }
  return -1;
}

修改

void Modify_adderss(struct address_book* table)
{
  assert(table);
  //判断通讯录是否为空
  if (table->conut == 0)
  {
    printf("通讯录为空\n");
    return;
  }
  //开始修改
  printf("你要修改人的名字是:");
  char arr[NAME];
  scanf("%s", arr);
  int idx = Seek_adderss(table, arr);
  if (idx != -1)
  {
    //进行修改
    printf("请开始修改\n");
    printf("修改名字:");
    scanf("%s", table->peple_address_num[idx].name);
    printf("修改年龄:");
    scanf("%d", &(table->peple_address_num[idx].age));
    printf("修改性别:");
    scanf("%s", table->peple_address_num[idx].sex);
    printf("修改电话:");
    scanf("%s", table->peple_address_num[idx].phone);
    printf("修改地址:");
    scanf("%s", table->peple_address_num[idx].address);
    printf("修改成功\n");
  }
  else
    printf("无这个人\n");
}

排序

//排序
void Sort_address(struct address_book* table)
{
  assert(table);
  int input;
  printf("输入你要排序的数字>1(名字),2(年龄),3(性别),4(电话),5(地址)<:");
  scanf("%d", &input);
  switch (input)
  {
    //名字
  case 1:
    qsort(table->peple_address_num, table->conut, sizeof(table->peple_address_num[0]), strsort);
    printf("成功");
    break;
  //年龄
  case 2:
    qsort(table->peple_address_num, table->conut, sizeof(table->peple_address_num[0]), strsort1);
    printf("成功");
    break;
  // 性别
  case 3:
    qsort(table->peple_address_num, table->conut, sizeof(table->peple_address_num[0]), strsort2);
    printf("成功");
    break;
  // 电话
  case 4:
    qsort(table->peple_address_num, table->conut, sizeof(table->peple_address_num[0]), strsort3);
    printf("成功");
    break;
  //地址
  case 5:
    qsort(table->peple_address_num, table->conut, sizeof(table->peple_address_num[0]), strsort4);
    printf("成功\n");
    break;
  default:
    printf("输入错误");
    break;
  }
}

//名字排序
int strsort(const void* e1, const void* e2)
{
  return strcmp(((struct People*)e1)->name, ((struct People*)e2)->name);
}
//年龄
int strsort1(const void* e1, const void* e2)
{
  return ((struct People*)e1)->age - ((struct People*)e2)->age;
}
//性别
int strsort2(const void* e1, const void* e2)
{
  return strcmp(((struct People*)e1)->sex, ((struct People*)e2)->sex);
}
//电话
int strsort3(const void* e1, const void* e2)
{
  return strcmp(((struct People*)e1)->phone, ((struct People*)e2)->phone);
}
//地址
int strsort4(const void* e1, const void* e2)
{
  return strcmp(((struct People*)e1)->address, ((struct People*)e2)->address);
}

最终的结构

#include "通讯录声明.h"
int main()
{
  //创建一个通讯表
  struct address_book  table;
  //初始化通讯表
  initialization(&table);
  int input = 0;
  printf("是否开始通讯录的操作(0(否)/1(是)):>");
  scanf("%d", &input);
  do
  {
    if (input != 0 && input != 1)
    {
      printf("输入错误,请重新输入\n");
      printf("是否开始通讯录的操作(0(否)/1(是)):>");
      scanf("%d", &input);
      continue;
    }
    int select;
    emun();
    printf("你要进行的行为是:>");
    scanf("%d", &select);
    switch (select)
    {
    case EXIT://结束
      break;
    case ADD://增
      Add_address(&table);
      table.conut++;
      printf("增加成功\n");
      break;
    case DEL://删
      Del_adderss(&table);
      break;
    case SEEK://查
      printf("你要查找人的名字是:");
      char arr[NAME];
      scanf("%s", arr);
      int i = Seek_adderss(&table, arr);
      if (i == -1)
        printf("无这个人\n");
      else
      {
        printf("显示如下:\n");
        printf("%-20s %-5s %-5s %-12s %-100s\n", "名字", "年龄", "性别", "电话", "地址");
        printf("%-20s ", table.peple_address_num[i].name);
        printf("%-5d ", table.peple_address_num[i].age);
        printf("%-5s ", table.peple_address_num[i].sex);
        printf("%-12s ", table.peple_address_num[i].phone);
        printf("%-100s\n", table.peple_address_num[i].address);
        
      }
      break;
    case MODIFY://修改
      Modify_adderss(&table);
      break;
    case SORT://排序
      Sort_address(&table);
      break;
    case SHOW://显示
      Show_address(&table);
      break;
    default:
      printf("你的操作有误,请重新操作\n");
      break;
    }
    if (select == 0)
    {
      break;
    }
  } while (input);
  printf("退出成功,欢迎下次光临,大佬慢走\n");
  return 0;
}

这个通讯录的问题

  1. 这里录入的信息是存放在内存中,只要程序或者掉电了就会丢失
  2. 这里的通讯录的大小是写死的,如果要实现通讯录满了要扩充就要使用到动态内存管理函数
  3. 函数调用主要是依赖查找函数,缺少这个不行

使用动态内存的方法

//动态开辟
struct address_book
{
  struct People *peple_address_num; //人的信息集合
  int conut; //统计人数
  int num_people;//当前开辟的大小
};

//增加
void Add_address(struct address_book* table)
{
  assert(table);
  //判断count的大小
  if (table->conut == table->num_people)
  {
    printf("通讯录已经满了\n");
    struct People * p = realloc(table->peple_address_num, sizeof(struct People) * (table->num_people + 2));
    if (p != NULL)
    {
      table->peple_address_num = p;
      table->num_people = table->num_people + 2;
      printf("增加空间成功\n");
    }
    else
    {
      perror("realloc");
      return;
    }

  }
  getchar();
  printf("输入名字:");
  gets(table->peple_address_num[table->conut].name);
  printf("输入年龄:");
  scanf("%d", &(table->peple_address_num[table->conut].age));
  getchar();
  printf("输入性别:");
  gets(table->peple_address_num[table->conut].sex);
  printf("输入电话号码:");
  gets(table->peple_address_num[table->conut].phone);
  printf("输入地址");
  gets(table->peple_address_num[table->conut].address);
}

我们只需更改一下这个通讯录的结构体和增加函数就可以实现动态开辟的方法

总结

这个通讯录大致来讲缺陷很多,如果要实现更加完美,我们就要使用后面的知识,代码我会上传到gitee里面有空可以看看,

相关文章
|
1天前
|
C语言
C语言进阶21收尾(编程练习)(atoi,strncpy,strncat,offsetof模拟实现+找单身狗+宏交换二进制奇偶位)(下)
C语言进阶21收尾(编程练习)(atoi,strncpy,strncat,offsetof模拟实现+找单身狗+宏交换二进制奇偶位)
6 0
|
1天前
|
程序员 编译器 C语言
C语言进阶⑳(程序环境和预处理)(#define定义宏+编译+文件包含)(中)
C语言进阶⑳(程序环境和预处理)(#define定义宏+编译+文件包含)
11 0
|
1天前
|
存储 编译器 C语言
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose(下)
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose
7 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
8 0
|
1天前
|
编译器 数据库 C语言
C语言进阶⑰(动态内存管理)四个动态内存函数+动态通讯录+柔性数组_malloc+free(上)
C语言进阶⑰(动态内存管理)四个动态内存函数+动态通讯录+柔性数组_malloc+free
9 0
C语言进阶⑰(动态内存管理)四个动态内存函数+动态通讯录+柔性数组_malloc+free(上)
|
1天前
|
编译器 C语言
C语言进阶⑯(自定义类型)项目:静态通讯录,增删查改排序打印。
C语言进阶⑯(自定义类型)项目:静态通讯录,增删查改排序打印。
11 1
|
1天前
|
C语言
C语言实现通讯录
C语言实现通讯录
8 0