C语言——史上最全通讯录讲解(附源码)
C语言——史上最全通讯录讲解(附源码)
- 一、开始界面的打印
- 二、对六大板块进行定义操作
- 三、对联系人进行初始化
- 四、对通讯录进行初始化
- 4.1动态版本
- 4.2静态版本
- 五、通讯录六大功能的具体实现
- 5.1判断是否需要扩容Checkcapcity
- 5.2添加联系人ADDcontact
- 5.3删除联系人 DELcontact
- 5.3.1 Findname
- 5.3.2删除联系人
- 5.4 查找联系人 SEARCHcontact
- 5.5 修改联系人MODIFYcontac
- 5.6对联系人进行排序SORTcontact
- 5.7销毁通讯录Destory
- 5.5显示联系人信息SHOWcontact
- 六、通讯录源码
- 6.1 Contact.h
- 6.2 Contact.c
- 6.3 test.c
- 6.4 代码运行
本次通讯录的实现,我将其分为6大板块,分别是添加联系人,删除联系人,展示联系人,修改联系人,查询指定联系人,将联系人按照姓名进行排序。
一、开始界面的打印
首先我们需要创建一个美观的界面,让我们所制作的通讯录看起来更加的规范,更加的整洁,而界面的制作我们在这里就简单的运用了一下printf函数,代码如下,当然大家也可以选择自己喜欢的样式去制作一个自己喜欢的开始界面。
void menu()
{printf("***************************\n");printf("*****1.add 2.del*****\n");printf("*****3.show 4.search*****\n");printf("*****5.modify 6.sort*****\n");printf("*****7.exit *****\n");printf("***************************\n");}
二、对六大板块进行定义操作
我们可以采用联合体进行对六大板块的一个定义操作,因为联合体里面的定义内容其本质上就是数字0,1,2…
enum option
{exit,add,del,show,search,modify,sort
};
三、对联系人进行初始化
在contact.h中对联系人进行初始化,这里我们采用结构体的方式,对联系人的个人信息进行一定的简单初始化,为了方便日后可能需要对数字重新定义的需求,这里我们采用typedef的方式定义一些变量
#define MAX 100
#define MAX_name 20
#define MAX_sex 5
#define MAX_tele 15
#define MAX_addr 20
#define DEFAULT_sz 3
#define INC_SZ 3
通讯录的联系人的初始化
typedef struct Peopleinformatin
{char name[MAX_name];char sex[MAX_sex];int age;char tele[MAX_tele];char addr[MAX_addr];
}Peopleinformatin;
四、对通讯录进行初始化
通讯录的初始化分为两个版本,静态版本和动态版本,其中动态版本可以通过坚持联系人的信息,来判断是否需要扩充容量。
4.1动态版本
void Initcontact(contact* pc)
{pc->data = (Peopleinformatin*)malloc(DEFAULT_sz * sizeof(Peopleinformatin));if (NULL == pc->data){printf("初始化空间失败:%s", strerror(errno));}pc->sz = 0;pc->capacity = DEFAULT_sz;
4.2静态版本
//静态版本
//初始化联系人
void Initcontact(contact* pc)
{pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));
}
五、通讯录六大功能的具体实现
5.1判断是否需要扩容Checkcapcity
该函数可以通过判断,以达到是否需要进行扩容的目的
int Checkcapcity(contact* pc)
{if (pc->sz == pc->capacity)//表明需要进行扩容{Peopleinformatin* ptr = (Peopleinformatin*)realloc(pc->data, (DEFAULT_sz + INC_SZ) * sizeof(Peopleinformatin));if (ptr == NULL){printf("扩容失败:%s", strerror(errno));return 0;}else{pc->data = ptr;pc->capacity += INC_SZ;printf("扩容成功:%d", pc->capacity);return 1;}return 1;}
}
5.2添加联系人ADDcontact
通过该函数达到添加联系人各项基本信息的目的,在使用该函数前,首先要利用Checkcapcity函数来判断是否要进行扩容操作,来达到存放联系人信息的目的。
void ADDcontact(contact* pc)
{if (Checkcapcity(pc) == 0){printf("扩容失败:%s", strerror(errno));return;}else{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++;}}
5.3删除联系人 DELcontact
对联系人进行删除操作时,我们需要先找到该联系人,所以我们先要创建一个函数来找到该联系人,在本次的通讯录中,我采用查找名字的方式,来查找联系人。
5.3.1 Findname
通过strcmp函数来比较字符串中的信息是否相同,以此来达到查找联系人的目的。
int Findname(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;}
5.3.2删除联系人
通过FIndname找到联系人之后,便可以进行删除操作了。在这里我们定义了DELcontact来进行删除操作,我们在这里采用覆盖的方式,将后一个联系人的信息把前一个联系人的信息进行覆盖。
void DELcontact(contact* pc)
{char name[MAX_name] = { 0 };//查找联系人printf("请输入要查找人的姓名:");scanf("%s", name);int pos = Findname(pc, name);if (pos == -1){printf("查询的联系人没有找到\n");}int i = 0;//删除操作for (i = 0; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}
5.4 查找联系人 SEARCHcontact
void SEARCHcontact(contact* pc)
{char name[MAX_name] = { 0 };printf("请输入要查找人的姓名:");scanf("%s", name);int ret = Findname(pc, name);if (ret == -1){printf("通讯录中没有该联系人\n");return;}//打印标题printf("%-10s %-5s %-10s %-20s %-10s\n", "姓名", "性别", "年龄", "电话", "地址");//打印数据printf("%-10s %-5s %-10d %-20s %-10s\n", pc->data[ret].name, pc->data[ret].sex, pc->data[ret].age, pc->data[ret].tele, pc->data[ret].addr);
}
5.5 修改联系人MODIFYcontac
首先对通过前文的Findname函数找到要修改的联系人信息,之后便可以对其进行修改操作。
void MODIFYcontact(contact* pc)
{char name[MAX_name] = { 0 };printf("请输入要修改联系人的姓名:");scanf("%s", name);int ret = Findname(pc, name);if (ret == -1){printf("通讯录中没有该联系人\n");return;}//修改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");
}
5.6对联系人进行排序SORTcontact
采用qsort对联系人按照姓名进行排序。
int cmp_by_name(const void* e1, const void* e2)
{return strcmp(((Peopleinformatin*)e1)->name, ((Peopleinformatin*)e2)->name);
}
void SORTcontact(contact* pc)
{qsort(pc->data, pc->sz, sizeof(Peopleinformatin), cmp_by_name);printf("修改成功\n");
}
5.7销毁通讯录Destory
通过**free释放所申请的空间,并将其置为NULL**。
void Destory(contact* pc)
{free(pc->data);pc->data = NULL;pc->capacity = NULL;pc->sz = NULL;printf("销毁内存成功\n");
}
5.5显示联系人信息SHOWcontact
void SHOWcontact(const contact* pc)
{//打印标题int i = 0;printf("%-10s %-5s %-10s %-20s %-10s\n", "姓名", "性别", "年龄", "电话", "地址");//打印数据for (i = 0; i < pc->sz; i++){printf("%-10s %-5s %-10d %-20s %-10s\n", pc->data[i].name, pc->data[i].sex, pc->data[i].age, pc->data[i].tele, pc->data[i].addr);}
}
六、通讯录源码
6.1 Contact.h
#pragma once
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>
#include<errno.h>
#define MAX 100
#define MAX_name 20
#define MAX_sex 5
#define MAX_tele 15
#define MAX_addr 20
#define DEFAULT_sz 3
#define INC_SZ 3typedef struct Peopleinformatin
{char name[MAX_name];char sex[MAX_sex];int age;char tele[MAX_tele];char addr[MAX_addr];
}Peopleinformatin;
//动态版本
typedef struct contact
{Peopleinformatin* data;//指向存放数据的空间int sz;//保存当前存放联系人的个数int capacity;//通讯录的容量}contact,*pcontact;//重新定义命名//初始化通讯录
void Initcontact(contact *pc);//销毁通讯录
void Destory(contact* pc);//添加联系人
void ADDcontact(contact* pc);//显示通讯录
void SHOWcontact(const contact* pc);//删除联系人
void DELcontact(contact* pc);//查询联系人
void SEARCHcontact(contact* pc);//修改联系人信息
void MODIFYcontact(contact* pc);//按名字对联系人信息进行排序
void SORTcontact(contact* pc);
6.2 Contact.c
#include"contact.h"
//动态版本的初始化
void Initcontact(contact* pc)
{pc->data = (Peopleinformatin*)malloc(DEFAULT_sz * sizeof(Peopleinformatin));if (NULL == pc->data){printf("初始化空间失败:%s", strerror(errno));}pc->sz = 0;pc->capacity = DEFAULT_sz;}//动态版本添加联系人
//判断是否需要进行扩容
int Checkcapcity(contact* pc)
{if (pc->sz == pc->capacity)//表明需要进行扩容{Peopleinformatin* ptr = (Peopleinformatin*)realloc(pc->data, (DEFAULT_sz + INC_SZ) * sizeof(Peopleinformatin));if (ptr == NULL){printf("扩容失败:%s", strerror(errno));return 0;}else{pc->data = ptr;pc->capacity += INC_SZ;printf("扩容成功:%d", pc->capacity);return 1;}return 1;}
}
void ADDcontact(contact* pc)
{if (Checkcapcity(pc) == 0){printf("扩容失败:%s", strerror(errno));return;}else{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++;}}//显示联系人
void SHOWcontact(const contact* pc)
{//打印标题int i = 0;printf("%-10s %-5s %-10s %-20s %-10s\n", "姓名", "性别", "年龄", "电话", "地址");//打印数据for (i = 0; i < pc->sz; i++){printf("%-10s %-5s %-10d %-20s %-10s\n", pc->data[i].name, pc->data[i].sex, pc->data[i].age, pc->data[i].tele, pc->data[i].addr);}
}
//查找名字的函数
int Findname(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(contact* pc)
{char name[MAX_name] = { 0 };//查找联系人printf("请输入要查找人的姓名:");scanf("%s", name);int pos = Findname(pc, name);if (pos == -1){printf("查询的联系人没有找到\n");}int i = 0;//删除操作for (i = 0; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}//查找联系人
void SEARCHcontact(contact* pc)
{char name[MAX_name] = { 0 };printf("请输入要查找人的姓名:");scanf("%s", name);int ret = Findname(pc, name);if (ret == -1){printf("通讯录中没有该联系人\n");return;}//打印标题printf("%-10s %-5s %-10s %-20s %-10s\n", "姓名", "性别", "年龄", "电话", "地址");//打印数据printf("%-10s %-5s %-10d %-20s %-10s\n", pc->data[ret].name, pc->data[ret].sex, pc->data[ret].age, pc->data[ret].tele, pc->data[ret].addr);
}//修改联系人信息
void MODIFYcontact(contact* pc)
{char name[MAX_name] = { 0 };printf("请输入要修改联系人的姓名:");scanf("%s", name);int ret = Findname(pc, name);if (ret == -1){printf("通讯录中没有该联系人\n");return;}//修改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");
}
//按名字对联系人信息进行排序
int cmp_by_name(const void* e1, const void* e2)
{return strcmp(((Peopleinformatin*)e1)->name, ((Peopleinformatin*)e2)->name);
}
void SORTcontact(contact* pc)
{qsort(pc->data, pc->sz, sizeof(Peopleinformatin), cmp_by_name);printf("修改成功\n");
}//销毁通讯录
void Destory(contact* pc)
{free(pc->data);pc->data = NULL;pc->capacity = NULL;pc->sz = NULL;printf("销毁内存成功\n");
}
6.3 test.c
#include"contact.h"
void menu()
{printf("**********************************\n");printf("**** 1.ADD 2.DEL ****\n");printf("**** 3.SHOW 4.SEARCH****\n");printf("**** 5.MODIFY 6.SORT ****\n");printf("**** 0.EXIT ****\n");printf("**********************************\n");
}
enum option
{EXIT,ADD,DEL,SHOW,SEARCH,MODIFY,SORT
};
int main()
{int input = 0;contact con;Initcontact(&con);//初始化通讯录menu();do{printf("请选择您要执行的功能:\n");scanf("%d", &input);switch (input){case EXIT:Destory(&con);printf("您已成功退出通讯录\n");break;case ADD:ADDcontact(&con);break;case DEL:DELcontact(&con);break;case SHOW:SHOWcontact(&con);break;case SEARCH:SEARCHcontact(&con);break;case MODIFY:MODIFYcontact(&con);break;case SORT:SORTcontact(&con);break;default:printf("输入错误,请重新输入\n");break;}} while (input);return 0;
}
6.4 代码运行
C语言——史上最全通讯录讲解(附源码)相关推荐
- 史上最全的vue.js源码解析(四)
虽然vue3已经出来很久了,但我觉得vue.js的源码还是非常值得去学习一下.vue.js里面封装的很多工具类在我们平时工作项目中也会经常用到.所以我近期会对vue.js的源码进行解读,分享值得去学习 ...
- Java毕设项目餐厅线上点菜系统计算机(附源码+系统+数据库+LW)
Java毕设项目餐厅线上点菜系统计算机(附源码+系统+数据库+LW) 项目运行 环境配置: Jdk1.8 + Tomcat8.5 + Mysql + HBuilderX(Webstorm也行)+ Ec ...
- 前端小白也能快速学会的博客园博客美化全攻略[附源码]
前端小白也能快速学会的博客园博客美化全攻略[附源码] 文章目录 前端小白也能快速学会的博客园博客美化全攻略[附源码] 美化方法论简介 准备工作 js权限申请 如何模仿一个博客园的自定义风格(样式css ...
- 用css使用html设置背景图片自适应,CSS怎么设置背景图片自适应全屏?附源码!...
不少同学在设置网站背景图片时会遇到这么一个问题:背景图片总是不能铺满整个屏幕,不是图片太小就是图片被过度放大,显得不太美观.那么 CSS 怎么设置背景图片自适应全屏呢?这篇文章告诉你. 实现效果: 源 ...
- JAVA文件上传详解(附源码)
文章目录 JAVA文件上传详解(附源码) 1.准备工作 2.使用类介绍 FileItem类 ServletFileUpload类 3.代码编写 JAVA文件上传详解(附源码) 在web应用中,文件上传 ...
- php弹幕反检测,【原理讲解附源码】找到B站弹幕的发送者
本帖最后由 厄斐琉斯 于 2020-7-31 23:19 编辑 特别鸣谢:感谢Hatsune_miku前辈在github上开源的部分源码 声明:任何人不得将其用于任何商业目的,否则后果自负! 前言:之 ...
- Java笔记-Java日常笔记-Java核心语言-史上最全Java笔记-Java烂笔头-实时更新(~v~)
阿一的日常Java笔记,实时更新,有什么问题可以留言交流一下,大家一起共同进步!!! 1.Java基础 1.1.基本语法 1.1.1.关键字 定义:被java赋予特殊含义的字符串(单词): 关 ...
- 史上最全IO讲解,以源码角度为你剖析,颠覆你的认知!
Java IO 是一个庞大的知识体系,很多人学着学着就会学懵了,包括我在内也是如此,所以本文将会从 Java 的 BIO 开始,一步一步深入学习,引出 JDK1.4 之后出现的 NIO 技术,对比 N ...
- C语言实现扫雷游戏(超详细讲解+全部源码)
电子信息 工科男 一点一点努力! 文章目录 前言 一.游戏介绍 二.游戏设计思路 二.具体步骤 1.创建test.c和game.c源文件以及 game.h头文件 2.创建菜单 3.创建雷盘 4.初始化 ...
最新文章
- 收藏!PyTorch常用代码段合集
- python在中小学教学中的应用-中小学Python教学的几点建议
- SparkSQL 将统计结果保存到Mysql
- 【Ubuntu】ubuntu物理机安装方法:U盘安装
- 谈谈nodejs爬虫程序利器——cheerio模块
- arp 命令最简单的小应用
- python的作者为什么要创造python_为什么要学习Python?老男孩Python开发
- 数组的fill方法_数组fill()方法以及JavaScript中的示例
- 手写简化版printf函数
- this_scope_call_apply_bind_柯里化 详细分析
- swift中高阶函数map、flatMap、filter、reduce
- oracle append 分区,insert append 到底扩展几个数据块?
- jsp浏览图像bean原理分析与改良-JSP实用教程(第三版)耿祥义 张跃平编著第4章例题4_9-动态获取文件夹中的文件并返回
- 估值过能预市下行风险
- 【2017年蓝桥杯Java-B组省赛题解】
- Linux如何进BIOS看硬盘,bios模式下怎么看硬盘
- Linus ,扎克伯格,雷军等巨佬的办公桌
- win10 提升来宾账户为管理员账户
- 计算机维修技术精解,《显卡维修知识精解——计算机维修技术精解》【价格 目录 书评 正版】_中图网...
- Kubernetes HPA 动态弹性扩缩容
热门文章
- python实现画板_一起看看python+pygame简单画板实现代码实例
- 天下贰任务剧情:醉卧沙场君莫笑
- Office365跨订阅迁移邮箱-批量导入用户PST文件
- 自定义Qt Designer插件
- 【原创】建立与保持时间裕量详细分析
- java计算机毕业设计springboot+vue医院碳排放管理平台系统
- YOLOV4+DeepSort车流量检测基础版
- 操作系统---利用“任务管理器”查找病毒
- 创业者必知的互联网思维之用户思维
- kaliarp欺骗注入_利用 Kali Linux 进行 Arp 欺骗,实现局域网断网攻击