本篇内容主要讲解“C语言怎么模拟实现动态通讯录”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C语言怎么模拟实现动态通讯录”吧!
目录
模拟实现通讯录总体架构一览图
文件执行任务
分模块实现
测试模块 test.c
头文件 功能函数声明 contact.h
功能函数逐一实现
1.模拟实现通讯录总体架构一览图
2.文件执行任务
3.分模块实现
测试模块 test.c
为了更好地展示,制作一个菜单,在菜单中有 添加,删除,查找,修改,排序,清空,退出的选项。
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
声明各类功能函数
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;}//把每个成员都设置为0pc->sz = 0; pc->capciaty = IN_NUM;}
添加联系人
当默认的空间被装满时,然后以后的每一次都开辟两个基本空间
void AddContact(contact* pc){//先判断通讯录中是否满了//if (pc->sz == MAX)//{//printf("通讯录已满,无法添加\n");//return;//}//动态判断人的个数是否满足3if (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->datapc->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");}
显示联系人信息
逐一打印联系人信息,注意之间的距离(保持美观)
//显示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);}}
删除联系人
在删除联系人之前,首先要查找要删除联系人的名字,然后进行删除,注意如何删除
让删除的这个单位的后一个单位去覆盖这个删除的单位(这样原来要删除的地方变成了后面一个值) 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");}
查找联系人
在删除联系人的时候有查找函数,在这里直接引用,并打印。这个人的信息。
//查找联系人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);}
修该联系人信息
还是现在通讯录中查找这个联系人,在进行输入修改
//修改信息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);}
排序联系人姓名
利用冒泡排序对联系人的名字进行排序(也可以使用快排)
//排序//交换名字,但是名字要和联系人的信息匹配//先比较名字,根据名字的大小,再排序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");}
清空联系人
在这里直接使用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");}
退出通讯录
手动开辟,手动释放
//退出程序,释放空间void ExitContact(contact* pc){//释放空间free(pc->data);pc->data = NULL;pc->sz = 0;pc->capciaty = 0;}
运行展示:
到此,相信大家对“C语言怎么模拟实现动态通讯录”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!