当前位置: 首页 > news >正文

【进阶C语言】静态版通讯录的实现(详细讲解+全部源码)

在这里插入图片描述
前言

📕作者简介:热爱跑步的恒川,正在学习C/C++、Java、Python等。
📗本文收录于C语言进阶系列,本专栏主要内容为数据的存储、指针的进阶、字符串和内存函数的介绍、自定义类型结构、动态内存管理、文件操作等,持续更新!
📘相关专栏Python,Java等正在发展,拭目以待!


📕本期内容恒川将会给大家带来实现通讯录的讲解,与上期所学的结构体内容相结合,我将会用C语言来实现通讯录的系统,并且能存放百人甚至千人的信息,每个人的信息包括:姓名、性别、年龄、电话、地址,并包含增加联系人、删除指定联系人、查找指定联系人、修改指定联系人、显示联系人信息、排序联系人等功能
📗通讯录和恒川之前写的三子棋和扫雷一样,都是多文件的形式,大家可以参考恒川之前C语言初阶系列的专栏


静态版本通讯录

  • 1. 配置运行环境
  • 2. 通讯录的实现
    • 2.1 通讯录的功能目录
    • 2.2 增加信息功能代码的实现
    • 2.3 显示信息功能代码的实现
    • 2.3 删除信息功能代码的实现
    • 2.4 查询信息功能代码的实现
    • 2.5 修改信息功能代码的实现
    • 2.6 按名字排序信息功能代码的实现
  • 3. 完整静态版本通讯录的全部源码
    • 3.1 contact.c
    • 3.2 contact.h
    • 3.3 test.c
  • 4. 静态版本通讯录的缺点

1. 配置运行环境

本通讯录运用到了三个文件
test.c //测试通讯录的相关功能
contact.h //声明
contact.c //通讯录的实现模块

2. 通讯录的实现

想要做通讯录,首要任务就是要把模块想好。
先打印一个通讯录的界面菜单

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

2.1 通讯录的功能目录

通讯录的功能有7种

  • 增加联系人
  • 删除指定联系人
  • 查找联系人
  • 修改联系人的信息
  • 对联系人的排序
  • 显示联系人的信息
  • 退出通讯录

创建人的信息的结构体类型
第一步是封装一个人的信息的结构体类型
由于封装的结构体类型的名字太长,总是写的话感觉太麻烦了
对 struct PeoInfo进行了typdef类型重命名
struct PeoInfp 改成 PeoInfp

//表示一个人的信息
typedef struct PeoInfo
{char name[20];int age;char sex[5];char tele[12];char addr[30];
}PeoInfo;

以上的数值如果以后会经常用到的话,可以用#define 来定义,方便以后修改

#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30

2.2 增加信息功能代码的实现

//增加通讯录信息
void AddContact(Contact* pc)
{if (DATA_MAX == pc->sz){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);printf("信息添加成功!\n");pc->sz++;
}

2.3 显示信息功能代码的实现

void ShowContact(const Contact* pc)
{int i = 0;//姓名      年龄      性别     电话      地址//zhangsan 20        男      123456    北京////打印标题printf("%-10s %-4s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");//打印数据for (i = 0; i < pc->sz; i++){printf("%-10s %-4d %-5s %-12s %-30s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);}
}

2.3 删除信息功能代码的实现

void DelContact(pContact pc)
{char name[MAX_NAME] = { 0 };if (pc->sz == 0){printf("通讯录为空,无法删除\n");return;}//删除//1. 找到要删除的人 - 位置(下标)printf("输入要删除人的名字:>");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("要删除的人不存在\n");return;}int i = 0;//2. 删除 - 删除pos位置上的数据for (i = pos; i<pc->sz-1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}

2.4 查询信息功能代码的实现

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

2.5 修改信息功能代码的实现

void ModifyContact(Contact* pc)
{char name[MAX_NAME] = {0};printf("请输入要修改人的名字:>");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){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].tele);printf("请输入地址:>");scanf("%s", pc->data[pos].addr);printf("修改成功\n");
}

2.6 按名字排序信息功能代码的实现

//按照名字来排序
int cmp_by_name(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}void SortContact(Contact* pc)
{qsort(pc->data, pc->sz, sizeof(PeoInfo), cmp_by_name);printf("排序成功\n");
}

3. 完整静态版本通讯录的全部源码

3.1 contact.c

#define _CRT_SECURE_NO_WARNINGS 1#include "contact.h"void InitContact(Contact* pc)
{pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));
}void AddContact(Contact* 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)
{int i = 0;//姓名      年龄      性别     电话      地址//hengchuan 20        男      123456    北京////打印标题printf("%-10s %-4s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");//打印数据for (i = 0; i < pc->sz; i++){printf("%-10s %-4d %-5s %-12s %-30s\n",pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);}
}static int FindByName(const Contact* pc, char name[])
{int i = 0;for (i = 0; i < pc->sz; i++){if (0 == strcmp(pc->data[i].name, name)){return i;}}return -1;
}void DelContact(pContact pc)
{char name[MAX_NAME] = { 0 };if (pc->sz == 0){printf("通讯录为空,无法删除\n");return;}//删除//1. 找到要删除的人 - 位置(下标)printf("输入要删除人的名字:>");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("要删除的人不存在\n");return;}int i = 0;//2. 删除 - 删除pos位置上的数据for (i = pos; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}void SearchContact(const Contact* pc)
{char name[MAX_NAME] = { 0 };printf("请输入要查找人的名字:>");scanf("%s", name);//查找int pos = FindByName(pc, name);if (pos == -1){printf("要查找的人不存在\n");return;}//打印printf("%-10s %-4s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");//打印数据printf("%-10s %-4d %-5s %-12s %-30s\n",pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].tele,pc->data[pos].addr);
}void ModifyContact(Contact* pc)
{char name[MAX_NAME] = { 0 };printf("请输入要修改人的名字:>");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){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].tele);printf("请输入地址:>");scanf("%s", pc->data[pos].addr);printf("修改成功\n");
}//按照名字来排序
int cmp_by_name(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}void SortContact(Contact* pc)
{qsort(pc->data, pc->sz, sizeof(PeoInfo), cmp_by_name);printf("排序成功\n");
}

3.2 contact.h

#pragma once#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30//表示一个人的信息
typedef struct PeoInfo
{char name[MAX_NAME];int age;char sex[MAX_SEX];char tele[MAX_TELE];char addr[MAX_ADDR];
}PeoInfo;//静态版本的设计
typedef struct Contact
{PeoInfo data[MAX];//存放数据int sz;//记录通讯录中的有效信息个数
}Contact, *pContact;//初始化通讯录
void InitContact(Contact* pc);//增加指定联系人
void AddContact(Contact* pc);//显示联系人信息
void ShowContact(const Contact* pc);//删除指定联系人
//void DelContact(Contact* pc);
void DelContact(pContact pc);//查找指定联系人
void SearchContact(const Contact* pc);//修改通讯录
void ModifyContact(Contact* pc);//排序通讯录元素
void SortContact(Contact* pc);

3.3 test.c

#define _CRT_SECURE_NO_WARNINGS 1
#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("*****    0. exit             ***\n");printf("********************************\n");
}enum Option
{EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SORT
};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:SearchContact(&con);break;case MODIFY:ModifyContact(&con);break;case SHOW:ShowContact(&con);break;case SORT:SortContact(&con);break;case EXIT:printf("退出通讯录\n");break;default:printf("选择错误\n");break;}} while (input);return 0;
}

4. 静态版本通讯录的缺点

缺点:

  1. 通讯录的大小是固定的 - 100个元素
  2. 当通讯录退出后,重新运行,之前的信息都丢了
    当前通讯录中的信息都是保存在内存中的,程序退出,内存就回收了,下一次重新运行程序,内存重新分配,之前的数据就不见了

所以恒川之后会给大家带来动态通讯录的版本,请大家拭目以待吧!!
如果这份博客对大家有帮助,希望各位给恒川一个免费的点赞作为鼓励,并评论收藏一下,谢谢大家!!!
制作不易,如果大家有什么疑问或给恒川的意见,欢迎评论区留言。

http://www.lryc.cn/news/59079.html

相关文章:

  • 【JavaWeb】后端(Maven+SpringBoot+HTTP+Tomcat)
  • 面试官:准备了一些springboot相关的面试题,快来看看吧
  • 原子的波尔模型、能量量子化、光电效应、光谱实验、量子态、角动量
  • 【如何使用Arduino控制WS2812B可单独寻址的LED】
  • 计算机基本知识扫盲(持续更)
  • 学习大数据需要什么语言基础
  • ElasticSearch——详细看看ES集群的启动流程
  • 【教学类-30-01】5以内加法题不重复(一页两份)(包含1以内、2以内、3以内、4以内、5以内加法,抽取最大不重复数量)
  • 写博客8年与人生第一个502万
  • 【华为OD机试真题】日志采集系统(javapython)
  • epoll源码剖析
  • Linux驱动开发——高级I/O操作(一)
  • 适配器模式:C++设计模式中的瑞士军刀
  • 【三十天精通Vue 3】 第三天 Vue 3的组件详解
  • SqlServer实用系统视图,你了解多少?
  • NodeJS Cluster模块基础教程
  • [C++笔记]vector
  • Python 迁移学习实用指南:1~5
  • 【CSS重点知识】属性计算的过程
  • Java避免死锁的几个常见方法(有测试代码和分析过程)
  • go binary包
  • CompletableFuture使用详解(IT枫斗者)
  • 4.15--设计模式之创建型之责任链模式(总复习版本)---脚踏实地,一步一个脚印
  • STM32+W5500实现以太网通信
  • 全网最详细,Jmeter性能测试-性能基础详解,终成测试卷王(一)
  • 人工智能概述
  • API接口安全—webservice、Swagger、WEBpack
  • 从前M个字母中取N个的无重复排列 [2*+]
  • ES forceMerge 强制段合并为什么会提升检索性能?
  • macOS Ventura 13.3.1 (22E261) Boot ISO 原版可引导镜像