C语言模拟实现动态通讯录
1.模拟实现通讯录总体架构一览图
2.文件执行任务
3.分模块实现
测试模块 test.c
1.为了更好地展示,制作一个菜单,在菜单中有 添加,删除,查找,修改,排序,清空,退出的选项。
2.因为起先要进入程序一趟,所以用do····while循环(输入选项来看具体操作,退出还是其他操作)
#include "contact.h" void menu() { printf("*****************************************\n"); printf("******** Contact ******\n"); printf("******** 1.add 2. del ******\n"); printf("******** 3.search 4.modify ******\n"); printf("******** 5.print 6.empty ******\n"); printf("******** 7.sort 0.exit ******\n"); printf("*****************************************\n"); } enum Option //为什么要使用枚举 //因为这样可以防止命名污染,而且使用枚举,枚举成员有默认初始值,默认从0开始,这样省去的诸多的代码量 { EXIT, ADD, DEL, SEARCH, MODIFY, PRINT, EMPTY, SORT, }; int main() { //先打印菜单,展示通讯录功能 int input = 0; //先进行设置一个通讯录 //设置每个人的信息 //初始化通讯录 //通讯录中的一个元素 contact con; //contact 是自定义数据类型,包括一个联系人的基本信息 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 PRINT: //显示 PrintContact(&con); break; case SORT: //实现名字排序 SortContact(&con); break; case EMPTY: //实现清空 EmptyContact(&con); break; case EXIT: //退出程序 ExitContact(&con); break; default: printf("输入错误,请重新输入\n"); } } while (input); return 0; }
头文件 功能函数声明 contact.h
1.声明各类功能函数
2.定义各个常量,把常量定义成通俗易懂的变量,便于在多处使用。
3.定义结构体,自定义类型中,有一个联系人的基本信息。
#include <stdio.h> #include <string.h> #include <stdlib.h> #define MAX_NAME 20 //定义姓名字符串的大小为20 #define MAX_SEX 10 //定义性别字符串的大小为10 #define MAX_TELE 12 //定义电话字符串的大小为12 #define MAX_ADDR 20 //定义地址字符串的大小为20 #define MAX 1000 //定义通讯录的最大容量为1000 #define IN_NUM 3 //在动态申请空间时默认空间为3 #define SET_NUM 2 //当基本信息大于3份时,开辟两个空间 //设置每一个人的信息 //通讯录规定要求一共有1000个人 typedef struct base { char name[MAX_NAME]; //姓名 char sex[MAX_SEX]; //性别 int age; //年龄 char tele[MAX_TELE]; //电话 char addr[MAX_ADDR]; //住址 }base; //设置1000人的通讯录 //静态版 //typedef struct contact //{ // // int sz; //计算当前通讯录中联系人的个数 // base data[MAX]; //存放联系人的信息 // //}contact; //动态初始化通讯录 typedef struct contact { //有个结构体类型中需要,监视通讯录人数的一项,还有当联系人为3人时,这时候要进行增容 int sz; //计算当前联系人的个数 base* data; //指向动态申请的空间,存放联系人的信息 int capciaty; //计算当前通讯录中的最大容量 }contact; //初始化通讯录 void InitContact(contact* pc); //添加联系人 void AddContact(contact* pc); //显示 void PrintContact(contact* pc); //删除联系人 void DelContact(contact* pc); //查找联系人 void SearchContact(contact* pc); //修改信息 void ModifyContact(contact* pc); //排序联系人信息 void SortContact(contact* pc); //清空联系人信息 void EmptyContact(contact* pc); //退出程序时,释放空间 void ExitContact(contact* pc);
功能函数逐一实现
contact.c 1.初始化通讯录
动态申请空间
默认在动态空间中存放3个基本单位信息
void InitContact(contact* pc) { pc->data = (base*)malloc(sizeof(base) * IN_NUM); if (pc->data == NULL) //如果空间开辟失败 //退出程序 { perror("InitContact"); return; } //把每个成员都设置为0 pc->sz = 0; pc->capciaty = IN_NUM; }
2.添加联系人
当默认的空间被装满时,然后以后的每一次都开辟两个基本空间
void AddContact(contact* pc) { //先判断通讯录中是否满了 //if (pc->sz == MAX) //{ // printf("通讯录已满,无法添加\n"); // return; //} //动态判断人的个数是否满足3 if (pc->sz == pc->capciaty) { printf("开始增容:\n"); //从新设置一个指针,存放新开辟的内存 base* ptr = (base*)realloc(pc->data, (pc->capciaty + SET_NUM) * sizeof(base)); //判断是否开辟成功 if (ptr == NULL) { printf("开辟失败\n"); perror("AddContact"); return; } else { printf("开辟成功\n"); //开辟成功的话,把ptr转交给data来维护,这样在内存释放的时候只需要释放pc->data pc->data = ptr; //增加基本信息数量 pc->capciaty += SET_NUM; } printf("增容完毕\n"); } //添加 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"); }
3.显示联系人信息
逐一打印联系人信息,注意之间的距离(保持美观)
//显示 void PrintContact(contact* pc) { //显示标题 printf("%-20s %-10s %-5s %-15s %-20s\n", "姓名", "性别", "年龄", "电话", "住址"); int i = 0; for (i = 0; i < pc->sz; i++) { printf("%-20s %-10s %-5d %-15s %-20s\n", pc->data[i].name, pc->data[i].sex, pc->data[i].age, pc->data[i].tele, pc->data[i].addr); } }
4.删除联系人
在删除联系人之前,首先要查找要删除联系人的名字,然后进行删除,注意如何删除
让删除的这个单位的后一个单位去覆盖这个删除的单位(这样原来要删除的地方变成了后面一个值) i = i+1
当通讯录中有被删除着的名字时,返回这个单位的下标
当通讯录中没有时,返回-1
//查找联系人 static int Find_name(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) { //如果通讯录是空的 if (pc->sz == 0) { printf("通讯为空,无需删除\n"); return; } //下进行查找被删除联系人的名字 char name[MAX_NAME]; printf("请输入要删除联系人的名字:"); scanf("%s", name); int ret = Find_name(pc, name); if (ret == -1) { printf("该联系人不存在\n"); return; } //删除 //删除项后边的一项,覆盖前面的一项 for (int i = ret; i < pc->sz; i++) { pc->data[i] = pc->data[i + 1]; } pc->sz--; printf("删除成功\n"); }
4.查找联系人
在删除联系人的时候有查找函数,在这里直接引用,并打印。这个人的信息。
//查找联系人 void SearchContact(contact* pc) { char name[MAX_NAME]; printf("请输入要查找联系人的名字:"); scanf("%s", name); int ret = Find_name(pc, name); if (ret == -1) { printf("该联系人不存在\n"); return; } printf("%-20s %-10s %-5s %-15s %-20s\n", "姓名", "性别", "年龄", "电话", "住址"); printf("%-20s %-10s %-5d %-15s %-20s\n", pc->data[ret].name, pc->data[ret].sex, pc->data[ret].age, pc->data[ret].tele, pc->data[ret].addr); }
5.修该联系人信息
还是现在通讯录中查找这个联系人,在进行输入修改
//修改信息 void ModifyContact(contact* pc) { char name[MAX_NAME]; printf("请输入要修改联系人的名字:"); scanf("%s", name); int ret = Find_name(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); }
6.排序联系人姓名
利用冒泡排序对联系人的名字进行排序(也可以使用快排)
//排序 //交换名字,但是名字要和联系人的信息匹配 //先比较名字,根据名字的大小,再排序 static void SwapByname(base* pa, base* pb) { base b; b = *pa; *pa = *pb; *pb = b; } void SortContact(contact* pc) { printf("开始排序\n"); //使用冒泡排序对联系人的名字进行排序 int i = 0; int j = 0; for (i = 0; i < pc->sz; i++) { for (j = 0; j < pc-> sz - i - 1; j++) { if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0) { //实现交换姓名 SwapByname(&pc->data[j], &pc->data[j + 1]); } } } printf("排序结束\n"); }
7.清空联系人
在这里直接使用sz–,就可以删除
//清空 void EmptyContact(contact* pc) { //如果原来的通讯录是空的就无须清空 if (pc->sz == 0) { printf("通讯录为空,无需清空\n"); return; } printf("开始清除数据:\n"); int num = pc->sz; for (int i = 0; i < num; i++) { pc->sz--; } printf("清空完毕\n"); }
8.退出通讯录
手动开辟,手动释放
//退出程序,释放空间 void ExitContact(contact* pc) { //释放空间 free(pc->data); pc->data = NULL; pc->sz = 0; pc->capciaty = 0; }
运行展示:
到此这篇关于C语言模拟实现动态通讯录的文章就介绍到这了,更多相关C语言 动态通讯录内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!
相关文章
- 这篇文章主要为大家详细介绍了C语言实现放烟花的程序,有音乐播放,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-23
- 本篇文章主要介绍C语言中char的知识,并附有代码实例,以便大家在学习的时候更好的理解,有需要的可以看一下...2020-04-25
- 这篇文章主要介绍了详解如何将c语言文件打包成exe可执行程序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-25
- 这篇文章主要为大家详细介绍了python实现学生通讯录管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-25
- free函数是释放之前某一次malloc函数申请的空间,而且只是释放空间,并不改变指针的值。下面我们就来详细探讨下...2020-04-25
详解C语言中的rename()函数和remove()函数的使用方法
这篇文章主要介绍了详解C语言中的rename()函数和remove()函数的使用方法,是C语言入门学习中的基础知识,需要的朋友可以参考下...2020-04-25- 这篇文章主要介绍了C语言中计算正弦的相关函数总结,包括正弦和双曲线正弦以及反正弦的函数,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了C语言中求和、计算平均值、方差和标准差的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-12-10
- 本篇文章主要讲解C语言 基本语法,这里提供简单的示例和代码来详细讲解C语言的基本语法,开始学习C语言的朋友可以看一下,希望能够给你带来帮助...2021-09-18
- 这篇文章主要介绍了C语言中send()函数和sendto()函数的使用方法,是C语言入门学习中的基础知识,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了C语言中memcpy 函数的用法详解的相关资料,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了使用C语言操作文件的基本函数整理,包括创建和打开以及关闭文件的操作方法,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了C语言中查找字符在字符串中出现的位置的方法,分别是strchr()函数和strrchr()函数的使用,需要的朋友可以参考下...2020-04-25
- 很多同学在学习c语言的时候是不是会碰到a++和++a都有甚么作用啊。今天我们就来探讨下...2020-04-25
- 今天小编就为大家分享一篇C语言实现从文件读入一个3*3数组,并计算每行的平均值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-25
- 下面小编就为大家带来一篇C语言实现时间戳转日期的算法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-04-25
- 本文给大家简单介绍下c实现linux下的数据库备份的方法和具体的源码,十分的实用,有需要的小伙伴可以参考下。...2020-04-25
- 这篇文章主要介绍了C语言之整数划分问题(递归法)实例代码的相关资料,需要的朋友可以参考下...2020-04-25
- 这篇文章主要对C语言中const关键字的用法进行了详细的分析介绍,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了c语言实现找最大值最小值位置查找,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-04