用C实现通讯录(详细讲解+源码)

 前言

📚作者简介:爱编程的小马,正在学习C/C++,Linux及MySQL..

📚以后会将数据结构收录为一个系列,敬请期待

● 本期内容会给大家带来通讯录的讲解,主要是利用结构体来实现通讯录,该通讯录可以存储几百人甚至是几千人的信息,每个信息包括:姓名,年龄,性别,电话以及地址。准备好了就跟着小马出发吧。


通讯录

 前言

1.通讯录环境及文件配置

2.通讯录的实现

2.1 通讯录的功能

2.2 通讯录的定义

2.3 录入人员信息的函数实现

2.4 定义检查人员是否存在函数

 2.5 删除通讯录中已经存在的信息函数实现

 2.6 查找通讯录成员函数

2.7 修改通讯录成员函数

2.8 显示通讯录

2.9 给通讯录排序

3.通讯录全部源码

3.1 test.c

3.2 contact.h

3.3 contact.c

总结


 

1. 通讯录环境及文件配置

本通讯录是在VS2019的环境下,需要创建三个文件,test.c ,contact.c ,contact.h

test.c //主函数,调用通讯录相关功能

contact.c //函数功能的实现

contact.h //函数头文件的包含及函数的声明

2. 通讯录的实现

2.1 通讯录的功能

2.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");
}

 通讯录的定义:

1、封装一个结构体信息用来存储人员信息

2、再需要一个结构体数组来管理这个人员信息(暂时能存储100个人)


#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 20
#define ADDR_MAX 30
#define ADD_ONCE 2
#define MAX 100
typedef struct peoinfo
{char name[NAME_MAX];int age;char sex[SEX_MAX];char tele[TELE_MAX];char addr[ADDR_MAX];
}peoinfo;
typedef struct contact
{peoinfo data [MAX];int sz;
}contact;

2.3 录入人员信息的函数实现

1、判断:如果人员信息录入满了就不再录入了

2、挨个录入姓名,年龄,性别,电话以及住址,录入完成后打印增加成功,然后记录人员信息的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].tele);printf("请输入地址:>");scanf("%s", pc->data[pc->sz].addr);pc->sz++;printf("添加成功\n");
}

2.4 定义检查人员是否存在函数

为什么要定义这个函数呢?因为两点原因:1、后面的删除,查找,修改人员信息是不是都要先确定这个人是否存在我们再进行下一步操作。2、在前面定义,后面直接引用即可,不用反复定义


int FindName(contact* pc,char name[])
{int i = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0)return i;}return -1;
}

 2.5 删除通讯录中已经存在的信息函数实现

1、判断:如果通讯录为空,就不要删除了,直接返回

2、如果不为空,我们就调用检查人员是否存在这个函数,如果存在,则继续,如果不存在,就返回

3、如果有这个人,那应该从这个人的地址往后,依次向前覆盖,最后总数sz-1是不是就完成了删除

void DelContact(contact* pc)
{char name[NAME_MAX];printf("请输入要删除人的名字:>");scanf("%s", name);if (pc->sz == 0){printf("通讯录为空,无法删除\n");return;}int ret = FindName(pc, name);if (ret == -1){printf("查无此人,无法删除请重试\n");return;}int i = 0;for (i = ret; i < ret - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}

 2.6 查找通讯录成员函数

1、判断:如果通讯录为空,不要查找了直接返回

2、调用检查人员存在函数,如果没有就直接返回,如果存在就直接打印人员信息

void SearchContact(contact* pc)
{char name[NAME_MAX];int i = 0;printf("请输入被查找人的名字:>");scanf("%s", name);int ret = FindName(pc, name);if (ret == -1){printf("查无此人\n");}else{printf("%-20s%-5s%-5s%-12s%-20s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-20s%-5d%-5s%-12s%-20s\n", pc->data[ret].name,pc->data[ret].age,pc->data[ret].sex,pc->data[ret].tele,pc->data[ret].addr);}
}

2.7 修改通讯录成员函数

1、判断:如果通讯录为空就不要修改了,直接返回

2、调用检查人员存在函数,如果没有就直接返回,如果存在就直接修改人员信息

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

2.8 显示通讯录

void ShowContact(contact* pc)
{assert(pc);if (pc->sz == 0)printf("通讯录为空,无需打印\n");else{int i = 0;for (i = 0; i < pc->sz; i++){printf("%-20s%-5s%-5s%-12s%-20s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-20s%-5d%-5s%-12s%-20s\n", pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].tele,pc->data[i].addr);}}
}

2.9 给通讯录排序

1、首先需要确定按什么排序

2、实现的思想是使用qsort函数

void menun()
{printf("******************************\n");printf("**** 1.按名字    2.按年龄 ****\n");printf("**** 3.按性别    4.按电话 ****\n");printf("**** 5.按地址             ****\n");printf("******************************\n");
}
int NAME(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->name, ((peoinfo*)p2)->name);
}int AGE(const void* p1, const void* p2)
{return (((peoinfo*)p1)->age- ((peoinfo*)p2)->age);
}
int SEX(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->sex, ((peoinfo*)p2)->sex);
}
int TELE(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->tele, ((peoinfo*)p2)->tele);
}
int ADDR(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->addr, ((peoinfo*)p2)->addr);
}
void SortContact(contact* pc)
{menun();int input = 0;printf("请输入排序的方式:>");scanf("%d", &input);int (*cmp[6])(const void* p1, const void* p2) = { NULL,NAME,AGE,SEX,TELE,ADDR};switch (input){case 1:qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);break;case 2:qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);break;case 3:qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);break;case 4:qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);break;case 5:qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);break;default:printf("输入非法\n");}printf("排序成功\n");
}

3. 通讯录全部源码

3.1 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;Init(&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");}} while (input);return 0;
}

3.2 contact.h

#pragma once
#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<stdlib.h>#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 20
#define ADDR_MAX 30
#define ADD_ONCE 2
#define MAX 100
typedef struct peoinfo
{char name[NAME_MAX];int age;char sex[SEX_MAX];char tele[TELE_MAX];char addr[ADDR_MAX];
}peoinfo;
typedef struct contact
{peoinfo data [MAX];int sz;
}contact;void Init(contact * pc);
void  AddContact(contact* pc);void ShowContact(contact*pc);void DelContact(contact* pc);void SearchContact(contact *pc);void ModifyContact(contact* pc);void SortContact(contact* pc);void free_contact(contact *pc);

3.3 contact.c

#define  _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"void Init(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].tele);printf("请输入地址:>");scanf("%s", pc->data[pc->sz].addr);pc->sz++;printf("添加成功\n");
}void ShowContact(contact* pc)
{assert(pc);if (pc->sz == 0)printf("通讯录为空,无需打印\n");else{int i = 0;for (i = 0; i < pc->sz; i++){printf("%-20s%-5s%-5s%-12s%-20s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-20s%-5d%-5s%-12s%-20s\n", pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].tele,pc->data[i].addr);}}
}//从后往前覆盖就好了,总数删除完毕之后再减一个int FindName(contact* pc,char name[])
{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)
{char name[NAME_MAX];printf("请输入要删除人的名字:>");scanf("%s", name);if (pc->sz == 0){printf("通讯录为空,无法删除\n");return;}int ret = FindName(pc, name);if (ret == -1){printf("查无此人,无法删除请重试\n");return;}int i = 0;for (i = ret; i < ret - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}void SearchContact(contact* pc)
{char name[NAME_MAX];int i = 0;printf("请输入被查找人的名字:>");scanf("%s", name);int ret = FindName(pc, name);if (ret == -1){printf("查无此人\n");}else{printf("%-20s%-5s%-5s%-12s%-20s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-20s%-5d%-5s%-12s%-20s\n", pc->data[ret].name,pc->data[ret].age,pc->data[ret].sex,pc->data[ret].tele,pc->data[ret].addr);}
}void ModifyContact(contact* pc)
{char name[NAME_MAX];int i = 0;printf("请输入要修改人的名字:>");scanf("%s", name);int ret = FindName(pc, name);if (ret == -1)printf("要修改的人不存在\n");else{printf("请输入名字:>");scanf("%s", pc->data[ret].name);printf("请输入年龄:>");scanf("%d", &pc->data[ret].age);printf("请输入性别:>");scanf("%s", pc->data[ret].sex);printf("请输入电话:>");scanf("%s", pc->data[ret].tele);printf("请输入地址:>");scanf("%s", pc->data[ret].addr);printf("修改成功\n");}}void menun()
{printf("******************************\n");printf("**** 1.按名字    2.按年龄 ****\n");printf("**** 3.按性别    4.按电话 ****\n");printf("**** 5.按地址             ****\n");printf("******************************\n");
}
int NAME(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->name, ((peoinfo*)p2)->name);
}int AGE(const void* p1, const void* p2)
{return (((peoinfo*)p1)->age- ((peoinfo*)p2)->age);
}
int SEX(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->sex, ((peoinfo*)p2)->sex);
}
int TELE(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->tele, ((peoinfo*)p2)->tele);
}
int ADDR(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->addr, ((peoinfo*)p2)->addr);
}
void SortContact(contact* pc)
{menun();int input = 0;printf("请输入排序的方式:>");scanf("%d", &input);int (*cmp[6])(const void* p1, const void* p2) = { NULL,NAME,AGE,SEX,TELE,ADDR};switch (input){case 1:qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);break;case 2:qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);break;case 3:qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);break;case 4:qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);break;case 5:qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);break;default:printf("输入非法\n");}printf("排序成功\n");
}

总结

上文就是通讯录的详细讲解和全部源码,下一节会给大家更新动态内存存储相关的知识。

如果这份博客对大家有帮助,希望各位给小马一个大大的点赞鼓励一下,如果喜欢,请收藏一下,谢谢大家!!!
制作不易,如果大家有什么疑问或给小马的意见,欢迎评论区留言。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/829553.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[ESP32]:TFLite Micro推理CIFAR10模型

[ESP32]&#xff1a;TFLite Micro推理CIFAR10模型 模型训练 数据集处理 from keras.datasets import cifar10 from keras.preprocessing.image import ImageDataGenerator from keras.models import Sequential, load_model, Model from keras.layers import Input, Dense, …

xLua详解

目录 环境准备xLua导入 C#调用LuaLua解析器Lua文件加载重定向Lua解析管理器全局变量的获取全局函数的获取List和Dictionary映射table类映射table接口映射tableLuaTable映射table Lua调用C#准备工作Lua使用C#类Lua调用C#枚举Lua使用C# 数组 List 字典数组List字典 Lua使用C#扩展…

解决NetworkManager覆盖/etc/resolv.conf的问题

发布时间&#xff1a;2024.4.27 问题 /etc/resolv.conf是Linux下DNS的配置文件。 但是NetworkManager会用覆盖它&#xff0c;导致我们每次都要重新配置。 解决办法 这是官方推荐的做法。或者你可以用resolveconf工具。 $ nm-connection-editor会调起一个界面&#xff0c;…

Python_AI库 matplotlib扩展知识

Python_AI库 matplotlib扩展知识 在数据分析和处理的领域里&#xff0c;可视化是一种不可或缺的手段。通过图形化的展示&#xff0c;我们可以更直观地理解数据的分布、趋势和关系。而matplotlib&#xff0c;作为Python中最为流行的数据可视化库之一&#xff0c;以其强大的功能…

【C++】简易二叉搜索树

目录 一、概念&#xff1a; 二、代码实现&#xff1a; 大致结构&#xff1a; 1、遍历&#xff1a; 2、insert 3、find 4、erase 三、总结&#xff1a; 一、概念&#xff1a; 二叉搜索树又称为二叉排序树&#xff0c;是一种具有特殊性质的二叉树&#xff0c;对于每一个节…

在虚拟环境中找到Qt Designer

Pyqt5中找到Qt Designer 安装Pyqt5和Qt Designer: pip install pyqt5-tools 假设Python的虚拟环境名为:d2l &#xff0c;虚拟环境在d2l文件夹中 D:\Software\d2l\Lib\site-packages\qt5_applications\Qt\bin 双击Qt designer启动 Pyside2中找到Qt Designer d2l是虚拟环境…

上位机图像处理和嵌入式模块部署(树莓派4b下使用sqlite3)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 嵌入式设备下面&#xff0c;有的时候也要对数据进行处理和保存。如果处理的数据不是很多&#xff0c;一般用json就可以。但是数据如果量比较大&…

rust前端web开发框架yew使用

构建完整基于 rust 的 web 应用,使用yew框架 trunk 构建、打包、发布 wasm web 应用 安装后会作为一个系统命令&#xff0c;默认有两个特性开启 rustls - 客户端与服务端通信的 tls 库update_check - 用于应用启动时启动更新检查&#xff0c;应用有更新时提示用户更新。nati…

Linux——终端

一、终端 1、终端是什么 终端最初是指终端设备&#xff08;Terminal&#xff09;&#xff0c;它是一种用户与计算机系统进行交互的硬件设备。在早期的计算机系统中&#xff0c;终端通常是一台带有键盘和显示器的电脑&#xff0c;用户通过它输入命令&#xff0c;计算机在执行命…

SpringBoot引入Layui样式总是出现404

一般出现Layui样式文件如css&#xff0c;js404的错误 解决方案 &#xff08;1&#xff09;首先将其中的静态资源下载resources/static中 &#xff08;2&#xff09;在启动类中重写方法 package com.gq.booksystem;import org.mybatis.spring.annotation.MapperScan; import …

centOS 7.9操作

名称日期版本作者centOS7.9操作2024.4.271.0lll 实验题目&#xff1a; 创建一个用户。 在创建的用户中再创建一个2024的目录。 在2024的下在创建一个 1---10的目录&#xff0c;再创建一个a--z.txt的文件。 在创建一个2024bak的目录。 再将当前用户的所有文件备份到2024ba…

【算法学习】线段树基础版

一 线段树 1.概念 线段树可以理解为一个二叉树&#xff0c;如果是利用线段树求区间的和&#xff0c;那么每个结点的权值维护的是结点所维护区间的和&#xff0c;再将该区间一分为二&#xff0c;分别交由左右儿子维护。 拿区间1 - 4的和来举例子&#xff0c; 根结点维护的是区…

JavaEE——Spring Boot入门

目录 &#x1f4da; JavaEE——Spring Boot入门 &#x1f527; 1. 新建Spring Boot项目 &#x1f6e0; 2. 添加pom依赖 &#x1f4dd; 3. 添加application.yml文件 &#x1f4c2; 4. 创建Dao层 &#x1f527; 5. 创建Service层 &#x1f5a5;️ 6. 创建Controller层及HT…

使用ClassFinal实现springboot项目jar包加密

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

docker容器技术篇:集群管理实战mesos+zookeeper+marathon(二)

docker集群管理实战mesoszookeepermarathon&#xff08;二&#xff09; 一 实验环境 操作系统&#xff1a;centos7.9 二 基础环境配置以及安装mesos 安装过程请点击下面的链接查看&#xff1a; 容器集群管理实战mesoszookeepermarathon&#xff08;一&#xff09; 三 安装…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 4月27日,星期六

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年4月27日 星期六 农历三月十九 1、 教育部&#xff1a;深入实施学生欺凌防治专项行动&#xff0c;对所有中小学校开展起底式大排查。 2、 商务部等七部门联合印发《汽车以旧换新补贴实施细则》&#xff0c;购车最高补贴1万…

【VBA】获取指定目录下的Excel文件,并合并所有excel中的内容。

1.新建一个excel表格。并创建两个Sheet&#xff0c;名字分别命名为FileList 和 All information。 2.按ALTF11进入 VBA编程模块&#xff0c;插入模块。 3.将如下 第五部分代码复制到模块中。 点击运行即可&#xff0c;然后就能提取指定目录下的所有excel文件信息并合并到一起…

连接oracle时出现ORA-12541:TNS:无监听程序的错误

遇到个问题&#xff0c;有一台windows serve 的服务器&#xff0c;这台服务器&#xff08;只部署了oracle&#xff09;忽然监听出问题了&#xff0c;提示 一、问题检查步骤&#xff1a; 1.winR--->cmd--->输入 lsnrctl status 查看监听的状态 如果监听器未运行&#…

【01】JAVASE-Java基础入门【从零开始学JAVA】

Java零基础系列课程-JavaSE基础篇 Lecture&#xff1a;波哥 Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机&#xff0c;Java 仍是企业和开发人员的首选开发平台。…

移远通信再推系列高性能卫星、5G、GNSS及三合一组合天线

4月23日&#xff0c;全球领先的物联网整体解决方案供应商移远通信正式宣布&#xff0c;再次推出多款高性能天线产品&#xff0c;以进一步满足物联网市场对高品质天线产品的需求。 其中包括卫星天线YETN001L1A、三合一组合天线YEMA300QXA和YEMN302Q1A&#xff0c;外部5G天线YECN…