C/【静态通讯录】

简介: C/【静态通讯录】


前言

 通讯录作为通讯录地址的书本,当今的通讯录可以涵盖多项内容。在手机,电脑等电子设备中也拥有这种功能,它里面涵盖多种内容,如:姓名、年龄、性别、地址、电话等等,本文就用C语言带大家去实现静态通讯录。

同往期的扫雷、三子棋,这次同样是分成三个模块:

测试的逻辑——test.c

功能的实现——contact.h

函数的声明——contact.c

目录

前言

一.功能实现

1.打印开始菜单

2.实现选择

3.创建结构体

4.初始化通讯录

5.功能实现

(1)添加联系人

(2)删除联系人

(3)查找联系人

(4)修改联系人

(5)显示所有联系人

(6)清空联系人

(7)排序联系人

二.完整代码

1.contact.h

2.contact.c

3.test.c


一.功能实现

1.打印开始菜单

和三子棋扫雷一样,我们都需要有一个开始菜单,告诉使用者有那些功能,对于我们的通讯录来说,无非就是添加联系人、删除联系人、查找联系人、修改联系人等等,那和三子棋扫雷一样,我们先将这些制作到菜单当中,让使用者选择

image.gif编辑

void menu()
{
  printf("*********************************\n");
  printf("*****  1.add     2.del       ****\n");
  printf("*****  3.search  4.modify    ****\n");
  printf("*****  5.show    6.sort      ****\n");
  printf("*****  7.empty   0.exit      ****\n");
  printf("*********************************\n");
}

image.gif

2.实现选择

选择选择也于扫雷三子棋大同小异,利用dowhile语句来实现多次循环,因为这次选择的功能很多,所以我们采用switch语句。

int input = 0;
do
{
    menu();
    printf("请选择:>");
    scanf("%d", &input);
    switch(input)
    {
    case 1:
        break;
    case 2:
        break;
    case 3:
        break;
    case 4:
        break;
    case 5:
        break;        
    case 6:;
        break;
    case 7:
        break;
    case 0:
        printf("退出通讯录\n");
        break;
    default:
        printf("选择错误,请重新选择\n");
        break;
    }
} while (input);

image.gif

3.创建结构体

我们要实现一个通讯录,那我们这些数据要放在哪里?这里就用到了我们的结构体,我们需要一个结构体,代表一个人的信息,名字,,年龄,性别,地址这些,那我们还需要确定的是,我们这个通讯录能存多少个人的信息,那我们就假设我们通讯里可以存放一百个人的,那这一百个人,我们去存放的时候怎么知道我们存了多少个人了信息了呢?那这里我们就可以在用一个结构体,里面放我们存放信息的结构体数组。

typedef struct People
{
  char name[20];
  int age;
  char sex[5];
  char addr[30];
  char tele[12];
}People;
//静态版本
typedef struct Contact
{
  People data[100];//存放人的信息
  int sz;//当前已经存放的信息的个数
}Contact;
//动态版本
typedef struct Contact
{
  People* data;//指向存放人的信息的空间
  int sz;//当前已经放的信息的个数
  int capacity;//当前通讯录的最大容量
}Contact;

image.gif

//创建通讯录
Contact con;

image.gif

4.初始化通讯录

那有了这些东西,在没有初始化之前,这些变量和数组里面存放的东西都是未知的,那就需要我们去初始化数组,我们可以直接用第二个结构体类型定义一个变量然后等于0,全初始化成0,我们也可以用一个函数menset来进行我们的初始化,将我们存放信息的数组内的初始化成我们想要的数值。

void InitContact(Contact* pc)//初始化
{
  assert(pc);
  pc->sz = 0;
  memset(pc->data, 0, sizeof(pc->data));
//使用memeset函数将p->data所指向的空间中的数据初始化为0
//操作的空间大小为sizeof函数所计算出的p->data所指向空间的大小,即整个无联系人数据的结构体数组data所占的空间的大小
}

image.gif

5.功能实现

(1)添加联系人

添加联系人,这个函数实现逻辑很简单,我们每次添加之前,先确定我们的通讯录是有位置的,所以我们可以先对sz进行一个判断,如果它等于100,就告诉我们通讯录已满,如果没有,就将下标为sz的位置替换成我们想要输入的信息,然后sz加加。

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].addr);
  printf("请输入电话:>");
  scanf("%s", pc->data[pc->sz].tele);
  pc->sz++;
}

image.gif

(2)删除联系人

删除联系人,我们可以采用输入名字,然后删除的方式,所以我们可以输入一个名字,然后开始对比数组内的每一个名字,相等就进去,跳出循环,然后开始让后面的信息往前面覆盖,最后让sz减减,这里我们要注意,我们后续实现的内容很多都要用到我们的查找,那我们就可以将查找部分分装成一个函数,返回一个整数,如果找不到,就返回-1,找到了,返回此时的下标位置。

int FindByName(const 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)
{
  assert(pc);
  char name[NAME_MAX] = { 0 };
  if (pc->sz == 0)
  {
    printf("通讯录为空,无法删除\n");
    return;
  }
  //删除
  //找到要删除的人
  printf("请输入要删除的人的名字:>");
  scanf("%s", name);
  int ret = FindByName(pc, name);
  if (-1 == ret)
  {
    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");
}

image.gif

(3)查找联系人

查找就和我们的删除思路大概一样了,同样调用我们的查找函数,找不到返回-1,告诉我们没有这个人,然后跳出函数,但是后面找到就与删除不一样了,我们将返回下标对应的内容打印出来,就找到了,这里找到联系人之后,信息打印在屏幕上,但是没有提示,对于我们来说可能就有点难确定哪个是哪个,所以这里我们加一个表头,对应每个信息。

void SearchContact(const Contact* pc)
{
  assert(pc);
  char name[NAME_MAX] = { 0 };
  printf("请输入要查找人的名字:>");
  scanf("%s", name);
  int pos = FindByName(pc, name);
  if (-1 == pos)
  {
    printf("要查找的人不存在\n");
    return;
  }
  //打印信息
  printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");
  printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[pos].name,
    pc->data[pos].age,
    pc->data[pos].sex,
    pc->data[pos].addr,
    pc->data[pos].tele);
}

image.gif

(4)修改联系人

修改也是用我们的查找函数,查找不到就告诉我们没有,然后跳出,查找到了就修改。

//修改联系人
void ModifyContact(Contact* pc)
{
  assert(pc);
  char name[NAME_MAX] = { 0 };
  printf("请输入要修改人的名字:>");
  scanf("%s", name);
  int pos = FindByName(pc, name);
  if (-1 == pos)
  {
    printf("要修改的人不存在\n");
    return;
  }
  printf("请输入名字:>");
  scanf("%s", pc->data[pos].name);
  printf("请输入年龄:>");
  scanf("%d", &(pc->data[pos].age));
  printf("请输入性别:>");
  scanf("%s", pc->data[pos].sex);
  printf("请输入地址:>");
  scanf("%s", pc->data[pos].addr);
  printf("请输入电话:>");
  scanf("%s", pc->data[pos].tele);
  printf("修改完成\n");
}

image.gif

(5)显示所有联系人

我们要显示所有联系人,只用打印出我们数组的所有内容就可以,为了方便我们查看,也打印上表头。

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

image.gif

(6)清空联系人

void ClearContact(Contact* pc)// 清空所有联系人 
{
  pc->sz = 0;
  printf("已清空通讯录\n");
}

image.gif

(7)排序联系人

排序,我们可以用qsort,进行排序,用名字来进行排序。

void sort_contact(Contact* pc)//以名字排序所有联系人 
{
  int i = 0;
  int j = 0;
  for (i = 0; i < pc->sz; i++)//冒泡法排序
  {
    for (j = 0; j < pc->sz - 1 - i; j++)
    {
      if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0)
      {
        People tmp = pc->data[j];
        pc->data[j] = pc->data[j + 1];
        pc->data[j + 1] = tmp;
      }
    }
  }
}

image.gif

二.完整代码

1.contact.h

#pragma once
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#define MAX 100
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 30
#define TELE_MAX 12
#define DEFAULT_SZ 3
#define INC_SZ 2
//人的信息(姓名,年龄,性别,地址,电话)
typedef struct People
{
  char name[NAME_MAX];
  int age;
  char sex[SEX_MAX ];
  char addr[ADDR_MAX];
  char tele[TELE_MAX];
}People;
typedef struct Contact
{
  People data[MAX];//存放人的信息
  int sz;//当前已经存放的信息的个数
}Contact;
//函数声明
//初始化通讯录
void InitContact(Contact* pc);
//增加联系人
void AddContact(Contact* pc);
//删除指定联系人
void DelContact(Contact* pc);
//显示通讯录中的信息
void ShowContact(const Contact* pc);
//查找指定联系人
void SearchContact(const Contact* pc);
//修改指定联系人
void ModifyContact(Contact* pc);
//排序
void sort_contact(Contact* pc);
//清空联系人
void ClearContact(Contact* pc);

image.gif

2.contact.c

#include "contact.h"
//函数定义
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].addr);
  printf("请输入电话:>");
  scanf("%s", pc->data[pc->sz].tele);
  pc->sz++;
}
void ShowContact(const Contact* pc)
{
  assert(pc);
  int i = 0;
  printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");
  for (i = 0; i < pc->sz; i++)
  {
    printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[i].name,
      pc->data[i].age,
      pc->data[i].sex,
      pc->data[i].addr,
      pc->data[i].tele);
  }
}
int FindByName(const 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)
{
  assert(pc);
  char name[NAME_MAX] = { 0 };
  if (pc->sz == 0)
  {
    printf("通讯录为空,无法删除\n");
    return;
  }
  //删除
  //找到要删除的人
  printf("请输入要删除的人的名字:>");
  scanf("%s", name);
  int ret = FindByName(pc, name);
  if (-1 == ret)
  {
    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(const Contact* pc)
{
  assert(pc);
  char name[NAME_MAX] = { 0 };
  printf("请输入要查找人的名字:>");
  scanf("%s", name);
  int pos = FindByName(pc, name);
  if (-1 == pos)
  {
    printf("要查找的人不存在\n");
    return;
  }
  //打印信息
  printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");
  printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[pos].name,
    pc->data[pos].age,
    pc->data[pos].sex,
    pc->data[pos].addr,
    pc->data[pos].tele);
}
void ModifyContact(Contact* pc)
{
  assert(pc);
  char name[NAME_MAX] = { 0 };
  printf("请输入要修改人的名字:>");
  scanf("%s", name);
  int pos = FindByName(pc, name);
  if (-1 == pos)
  {
    printf("要修改的人不存在\n");
    return;
  }
  printf("请输入名字:>");
  scanf("%s", pc->data[pos].name);
  printf("请输入年龄:>");
  scanf("%d", &(pc->data[pos].age));
  printf("请输入性别:>");
  scanf("%s", pc->data[pos].sex);
  printf("请输入地址:>");
  scanf("%s", pc->data[pos].addr);
  printf("请输入电话:>");
  scanf("%s", pc->data[pos].tele);
  printf("修改完成\n");
}
void sort_contact(Contact* pc)//以名字排序所有联系人 
{
  int i = 0;
  int j = 0;
  for (i = 0; i < pc->sz; i++)//冒泡法排序
  {
    for (j = 0; j < pc->sz - 1 - i; j++)
    {
      if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0)
      {
        People tmp = pc->data[j];
        pc->data[j] = pc->data[j + 1];
        pc->data[j + 1] = tmp;
      }
    }
  }
}
void ClearContact(Contact* pc)// 清空所有联系人 
{
  pc->sz = 0;
  printf("已清空通讯录\n");
}

image.gif

3.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.sort      ****\n");
  printf("*****  7.empty   0.exit      ****\n");
  printf("*********************************\n");
}
int main()
{
  int input = 0;
  Contact con;
  InitContact(&con);
  do
  {
    menu();
    printf("请选择:>");
    scanf("%d", &input);
    switch (input)
    {
    case 1:
      AddContact(&con);
      break;
    case 2:
      DelContact(&con);
      break;
    case 3:
      SearchContact(&con);
      break;
    case 4:
      ModifyContact(&con);
      break;
    case 5:
      ShowContact(&con);
      break;
    case 6:
            sort_contact(&con);
      break;
    case 7:
      ClearContact(&con);
      break;
    case 0:
      printf("退出通讯录\n");
      break;
    default:
      printf("选择错误,请重新选择\n");
      break;
    }
  } while (input);
  return 0;
}

image.gif


本篇文章就到此为止了,希望佬们多多支持!😘😘

相关文章
|
监控 物联网 视频直播
流量卡类型及其适用场景
不同流量卡的使用场景可以根据其特点、套餐内容、价格以及用户的具体需求来划分。以下是一些常见的流量卡类型及其适用场景:
|
机器学习/深度学习 人工智能 搜索推荐
AIGC的五个特点
【1月更文挑战第11天】AIGC的五个特点
1510 3
AIGC的五个特点
|
8月前
|
机器学习/深度学习 人工智能 算法
普通人怎么学人工智能?这些隐藏学习秘籍大揭秘,生成式人工智能认证(GAI认证)来助力
在人工智能(AI)快速发展的今天,普通人学习AI已成为必然趋势。本文从明确学习目标与路径、利用多元化资源、注重实践应用、关注GAI认证及持续自我提升五个方面,为普通人提供系统化的AI学习指南。通过设定目标、学习编程语言、参与项目实践和获取专业认证,普通人可逐步掌握AI技能,在未来职场中占据优势并开启智能时代新篇章。
|
8月前
|
人工智能 安全 5G
5G网络安全全解析——新机遇与潜在风险
5G网络安全全解析——新机遇与潜在风险
368 4
|
9月前
|
Swift
DeepSeek开源Janus-Pro多模态理解生成模型,魔搭社区推理、微调最佳实践
DeepSeek开源Janus-Pro多模态理解生成模型,魔搭社区推理、微调最佳实践
484 1
|
10月前
|
安全 BI 数据安全/隐私保护
基于条件的访问控制——RBAC
基于角色的访问控制(RBAC)根据员工的角色和职责分配权限,确保用户仅能访问所需资源,降低数据泄露风险。通过ADManager Plus等工具,企业可以高效管理权限,减少手动操作,提升安全性并保护敏感信息。RBAC的核心原则是最小权限,即只为员工分配完成工作所需的权限。这不仅提高了工作效率,还减少了未经授权访问的风险,是防范网络威胁的有效手段。
220 3
|
人工智能 前端开发 PyTorch
【AI系统】动态图与静态图转换
从 TensorFlow、PyTorch 到 PaddlePaddle、MindSpore、MegEngine,主流 AI 框架经历了动静分离、动静结合到动静统一的发展过程。这些框架通过动态图转静态图技术,实现了计算效率与灵活性的平衡,显著提升了 AI 开发效率和产品应用的便利性。
391 14
|
缓存 监控 负载均衡
万字讲解API网关的来龙去脉【珍藏】
万字讲解API网关的来龙去脉【珍藏】
3078 1
万字讲解API网关的来龙去脉【珍藏】
|
缓存 Ubuntu Linux
如何在 Linux 中查找命令的执行时间?
【4月更文挑战第24天】
574 1
|
开发框架 程序员 开发者
Python GUI编程:从入门到精通3.2 GUI编程:学习使用Tkinter、PyQt或wxPython等库创建图形用户界面。
Python GUI编程:从入门到精通3.2 GUI编程:学习使用Tkinter、PyQt或wxPython等库创建图形用户界面。
315 1

热门文章

最新文章