文章目录

 

动态通讯录的实现


——接上篇1.0版本静态通讯录的优化2.0版本

C语言实战小项目——通讯录1.0—— 博客入口

 

一.通讯录的各项功能及主体框架

 

  本次优化版本与上一次的1.0版本相比,改变了原有的固定内存存储通讯录联系人的方式。

  原来的存储联系人方式是我们规定一个数组存储1000个结构体进行存储联系人的各种信息,但是有时候我们用不了这么多的空间,没有那么多的联系人,那样我们开辟的内存空间就浪费了,所以这次我们的通讯录做了以下优化:

1.  通讯录我们开辟的动态内存空间默认最大的联系人数量是2个

2.  如果再添加联系人,我们将调整动态内存空间的大小,再次增加两个联系人的数量,这样极大的节约了空间的占有率。

3.  我们开辟的动态内存需要free ,防止内存泄漏的问题,所以在EXIT的功能后添加了DestroyContact函数来对开辟的空间进行释放。

 

1.通讯录的要求实现功能

 

0.退出菜单
1.添加联系人信息
2.删除指定名字的联系人信息
3.修改联系人的信息
4.查找好友的信息
5.展示通讯录联系人信息

  我们根据通讯录的各项功能进行编写页面菜单

2.页面菜单

void menu(){//打印通讯录菜单//0.退出菜单//1.添加联系人信息//2.删除指定名字的联系人信息//3.修改联系人的信息//4.查找好友的信息//5.展示通讯录联系人信息//6.对通讯录指定信息进行排序printf("*************************************************\n");printf("**********  ——欢迎来到通讯录菜单——  *********\n");printf("**********      0.退出菜单              *********\n");printf("**********      1.添加联系人信息        *********\n");printf("*********       2.删除联系人信息        *********\n");printf("*********       3.修改联系人信息        *********\n");printf("*********       4.查找联系人信息        *********\n");printf("*********       5.展示联系人信息        *********\n");printf("*************************************************\n");}

 

3.通讯录的主体框架实现

 

//将菜单的功能一一列举出来,以枚举的类型呈现enum{
	EXIT,
	ADD,
	DEL,
	MODIFY,
	SEARCH,
	SHOW,};int main(){int input = 0;//创建通讯录struct Contact con;  //Con就是通讯录,里面包含1000个人的信息,及sizeInitContact(&con);do{menu();printf("请选择功能:>");scanf("%d", &input);switch (input){case ADD:AddContact(&con);break;case DEL:DelContact(&con);break;case MODIFY :MotifyContact(&con);break;case SEARCH :SearchContact(&con);break;case SHOW:ShowContact(con);break;case EXIT:DestroyContact(&con);break;default:printf("选择错误,请重新输入!!\n");break;}} while(input);return 0;}


  我们用枚举类型将功能一一列举出来,同时每一个枚举成员也代表着对应的数字,我们在switch ...case 语句中也不用 case 1,case 2来记录每一功能对应的数字了,直接以case ADD,case DEL表示,更加直接了当。

4.通讯录初始化及个人信息的表示

 

#define _CRT_SECURE_NO_WARNINGS 1#define MAX 1000#define MAX_name 20#define MAX_tel 20#define MAX_sex 5#define MAX_addr 30#define DEFAULT_SZ 2struct  PeoInfor{char name[MAX_name];int age;char sex[MAX_sex];char tel[MAX_tel];char addr[MAX_addr];};//struct  Contact//{//	struct  PeoInfor date[MAX];  //  存放个人信息//	int size;                   //记录当前已有的元素个数//};//通讯录信息的动态内存的建立struct  Contact{struct  PeoInfor* date;  //  存放个人信息int size;                 //表示当前通讯录的联系人的数量int capacity;            //表示当天通讯录的联系人的最大空间能容纳的联系人数量};//动态内存的初始化void InitContact(struct  Contact * ps){
	ps->date = (struct PeoInfor *)malloc(DEFAULT_SZ * sizeof(struct PeoInfor));if (ps->date == NULL){printf("通讯录初始化失败");exit(1);}
	ps->size = 0;
	ps->capacity = 2;}

 

二、功能函数的具体实现

 

1.增加联系人的信息

 

void AddContact(struct Contact* ps){if (ps->size == ps->capacity){//增容struct PeoInfor * ptr = realloc(ps->date, (ps->capacity + 2)*sizeof(struct PeoInfor));if (ptr == NULL){printf("增容失败\n");return;}else{printf("增容成功\n");
			ps->capacity += 2;}}printf("请输入姓名:>");scanf("%s", ps->date[ps->size].name);printf("请输入年龄:>");scanf("%d", &(ps->date[ps->size].age));printf("请输入性别:>");scanf("%s", ps->date[ps->size].sex);printf("请输入电话:>");scanf("%s", ps->date[ps->size].tel);printf("请输入地址:>");scanf("%s", ps->date[ps->size].addr);
		ps->size++;printf("添加成功\n");}

 

2.删除联系人的信息

 

void DelContact(struct Contact *ps){ //  查找要删除的人在什么位置,根据名字char  name[MAX_name];printf("请输入要删除的联系人名字:>");scanf("%s", name);int i = 0;int j = 0;//查找名字for (i = 0; i < ps->size; i++){if (0 == strcmp(name, ps->date[j].name)){break;}}
	
	 if (i==ps->size)   // i从循环里出来,strcmp还是不等于0{printf("未找到该联系人的信息\n");}
	 else
	 {
		 for (j = i; j < ps->size; j++)
		 {
			 ps->date[j] = ps->date[j + 1];
			 
		 }
	 }
	 ps->size--;
	 printf("删除成功\n");}

 

3.修改联系人的信息

 

void MotifyContact(struct Contact *ps){char  name[MAX_name];printf("请输入要删除的联系人名字:>");scanf("%s", name);int i = 0;//查找名字for (i = 0; i < ps->size; i++){if (0 == strcmp(name, ps->date[i].name)){break;}}if (i == ps->size)   // i从循环里出来,strcmp还是不等于0{printf("未找到该联系人的信息\n");}//表示找到该联系人//对下标为i的联系人信息进行修改else{printf("请输入姓名:>");scanf("%s", ps->date[i].name);printf("请输入年龄:>");scanf("%d", &(ps->date[i].age));printf("请输入性别:>");scanf("%s", ps->date[i].sex);printf("请输入电话:>");scanf("%s", ps->date[i].tel);printf("请输入地址:>");scanf("%s", ps->date[i].addr);}printf("修改成功\n");}

 

4.查找联系人的信息

 

void SearchContact(struct Contact *ps){char  name[MAX_name];printf("请输入要查找的联系人名字:>");scanf("%s", name);int i = 0;//查找名字for (i = 0; i < ps->size; i++){if (0 == strcmp(name, ps->date[i].name)){break;}}if (i == ps->size)   // i从循环里出来,strcmp还是不等于0{printf("未找到该联系人的信息\n");}//表示找到该联系人//对下标为i的联系人信息进行显示else{printf("%10s\t%4s\t%5s\t%12s\t%20s\n", "名字", "年龄", "性别", "电话", "地址");printf("%10s\t%4d\t%5s\t%12s\t%20s\n",
			ps->date[i].name,
			ps->date[i].age,
			ps->date[i].sex,
			ps->date[i].tel,
			ps->date[i].addr);}}

 

5.展示通讯录联系人信息

 

void ShowContact(struct Contact ps){if (ps.size == 0){printf("通讯录为空,无法展示\n");}else{printf("%10s\t%4s\t%5s\t%12s\t%20s\n","名字","年龄","性别","电话","地址");int i = 0;for (i = 0; i < ps.size; i++){printf("%10s\t%4d\t%5s\t%12s\t%20s\n", 
				ps.date[i].name, 
				ps.date[i].age,
				ps.date[i].sex,
				ps.date[i].tel,
				ps.date[i].addr);}}}

 

整体代码展示

 

1.test.c 通讯录主体框架测试文件

 

#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>#include "contact.h"#include <string.h>void menu(){//打印通讯录菜单//0.退出菜单//1.添加联系人信息//2.删除指定名字的联系人信息//3.修改联系人的信息//4.查找好友的信息//5.展示通讯录联系人信息//6.对通讯录指定信息进行排序printf("*************************************************\n");printf("**********  ——欢迎来到通讯录菜单——  *********\n");printf("**********      0.退出菜单              *********\n");printf("**********      1.添加联系人信息        *********\n");printf("*********       2.删除联系人信息        *********\n");printf("*********       3.修改联系人信息        *********\n");printf("*********       4.查找联系人信息        *********\n");printf("*********       5.展示联系人信息        *********\n");printf("*************************************************\n");}//将菜单的功能一一列举出来,以枚举的类型呈现enum{
	EXIT,
	ADD,
	DEL,
	MODIFY,
	SEARCH,
	SHOW,};int main(){int input = 0;//创建通讯录struct Contact con;  //Con就是通讯录,里面包含1000个人的信息,及sizeInitContact(&con);do{menu();printf("请选择功能:>");scanf("%d", &input);switch (input){case ADD:AddContact(&con);break;case DEL:DelContact(&con);break;case MODIFY :MotifyContact(&con);break;case SEARCH :SearchContact(&con);break;case SHOW:ShowContact(con);break;case EXIT:DestroyContact(&con);break;default:printf("选择错误,请重新输入!!\n");break;}} while(input);return 0;}

 

2.contact.c 通讯录函数文件

 

#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>#include <string.h>#include "contact.h"#include <stdlib.h>//静态通讯录的信息初始化//void InitContact(struct  Contact* ps)//{//	memset(ps->date, 0, sizeof(ps->date));//	ps->size = 0;   //设置通讯录的元素有0个//}//动态通讯录的信息初始化void InitContact(struct  Contact * ps){
	ps->date = (struct PeoInfor *)malloc(DEFAULT_SZ * sizeof(struct PeoInfor));if (ps->date == NULL){printf("通讯录初始化失败");exit(1);}
	ps->size = 0;
	ps->capacity = 2;}//静态内存增添联系人的信息//void AddContact(struct Contact* ps)//{//	if (ps->size == MAX)//	{//		printf("该通讯录空间已满,无法储存\n");//	}//	else//	{//		printf("请输入姓名:>");//		scanf("%s", ps->date[ps->size].name);//		printf("请输入年龄:>");//		scanf("%d", &(ps->date[ps->size].age));//		printf("请输入性别:>");//		scanf("%s", ps->date[ps->size].sex);//		printf("请输入电话:>");//		scanf("%s", ps->date[ps->size].tel );//		printf("请输入地址:>");//		scanf("%s", ps->date[ps->size].addr);//		ps->size++;//		printf("添加成功\n");//	}////}//动态内存实现增添联系人的信息void AddContact(struct Contact* ps){if (ps->size == ps->capacity){//增容struct PeoInfor * ptr = realloc(ps->date, (ps->capacity + 2)*sizeof(struct PeoInfor));if (ptr == NULL){printf("增容失败\n");return;}else{printf("增容成功\n");   //如果增容成功,那么ptr的值要赋给 ps->date;   // ptr是realloc 开辟的内存,可能返回原来ps->date的地址,也可能是一个新的内存空间的地址
			ps->date = ptr;
			ps->capacity += 2;}}printf("请输入姓名:>");scanf("%s", ps->date[ps->size].name);printf("请输入年龄:>");scanf("%d", &(ps->date[ps->size].age));printf("请输入性别:>");scanf("%s", ps->date[ps->size].sex);printf("请输入电话:>");scanf("%s", ps->date[ps->size].tel);printf("请输入地址:>");scanf("%s", ps->date[ps->size].addr);
		ps->size++;printf("添加成功\n");}void ShowContact(struct Contact ps){if (ps.size == 0){printf("通讯录为空,无法展示\n");}else{printf("%10s\t%4s\t%5s\t%12s\t%20s\n","名字","年龄","性别","电话","地址");int i = 0;for (i = 0; i < ps.size; i++){printf("%10s\t%4d\t%5s\t%12s\t%20s\n", 
				ps.date[i].name, 
				ps.date[i].age,
				ps.date[i].sex,
				ps.date[i].tel,
				ps.date[i].addr);}}}void DelContact(struct Contact *ps){ //  查找要删除的人在什么位置,根据名字char  name[MAX_name];printf("请输入要删除的联系人名字:>");scanf("%s", name);int i = 0;int j = 0;//查找名字for (i = 0; i < ps->size; i++){if (0 == strcmp(name, ps->date[j].name)){break;}}
	
	 if (i==ps->size)   // i从循环里出来,strcmp还是不等于0{printf("未找到该联系人的信息\n");}
	 else
	 {
		 for (j = i; j < ps->size; j++)
		 {
			 ps->date[j] = ps->date[j + 1];
			 
		 }
	 }
	 ps->size--;
	 printf("删除成功\n");}void MotifyContact(struct Contact *ps){char  name[MAX_name];printf("请输入要删除的联系人名字:>");scanf("%s", name);int i = 0;//查找名字for (i = 0; i < ps->size; i++){if (0 == strcmp(name, ps->date[i].name)){break;}}if (i == ps->size)   // i从循环里出来,strcmp还是不等于0{printf("未找到该联系人的信息\n");}//表示找到该联系人//对下标为i的联系人信息进行修改else{printf("请输入姓名:>");scanf("%s", ps->date[i].name);printf("请输入年龄:>");scanf("%d", &(ps->date[i].age));printf("请输入性别:>");scanf("%s", ps->date[i].sex);printf("请输入电话:>");scanf("%s", ps->date[i].tel);printf("请输入地址:>");scanf("%s", ps->date[i].addr);}printf("修改成功\n");}void SearchContact(struct Contact *ps){char  name[MAX_name];printf("请输入要查找的联系人名字:>");scanf("%s", name);int i = 0;//查找名字for (i = 0; i < ps->size; i++){if (0 == strcmp(name, ps->date[i].name)){break;}}if (i == ps->size)   // i从循环里出来,strcmp还是不等于0{printf("未找到该联系人的信息\n");}//表示找到该联系人//对下标为i的联系人信息进行显示else{printf("%10s\t%4s\t%5s\t%12s\t%20s\n", "名字", "年龄", "性别", "电话", "地址");printf("%10s\t%4d\t%5s\t%12s\t%20s\n",
			ps->date[i].name,
			ps->date[i].age,
			ps->date[i].sex,
			ps->date[i].tel,
			ps->date[i].addr);}}//对开辟的动态内存空间进行释放,防止内存泄漏void DestroyContact(struct Contact *ps){free(ps->date);
	ps->date = NULL;
	ps->size = 0;
	ps->capacity = 0;}

 

3.contact.h 宏定义及函数声明文件

 

#define _CRT_SECURE_NO_WARNINGS 1#define MAX 1000#define MAX_name 20#define MAX_tel 20#define MAX_sex 5#define MAX_addr 30#define DEFAULT_SZ 2  //通讯录系统默认的内存存储的联系人数量struct  PeoInfor{char name[MAX_name];int age;char sex[MAX_sex];char tel[MAX_tel];char addr[MAX_addr];};//静态通讯录的结构体创建//struct  Contact//{//	struct  PeoInfor date[MAX];  //  存放个人信息//	int size;                   //记录当前已有的元素个数//};//动态通讯录的结构体创建struct  Contact{struct  PeoInfor* date;  //  存放个人信息int size;                 //表示当前通讯录的联系人的数量int capacity;};// 声明函数void InitContact(struct  Contact* ps);     //通讯录信息初始化void AddContact(struct Contact* ps);      //增加联系人相关信息void ShowContact(struct Contact ps);     //展示联系人相关信息void DelContact(struct Contact *ps);    //删除联系人相关信息void MotifyContact(struct Contact *ps);   //修改联系人相关信息void SearchContact(struct Contact *ps);  //搜索联系人相关信息void DestroyContact(struct Contact *ps);  //程序结束后释放开辟的动态内存,防止内存泄漏

 

小结

 

  我们写的通讯录实现了动态内存空间管理的功能,我们可以在这个程序内进行以上增删改查功能,但是我们退出了这个程序以后,我们存储的联系人信息将全部丢失,无法保存在一个固定的文件里,所以仍然存在限制和缺点。

 

  这就是通讯录的2.0版本,后续将持续更新,我们将在3.0版本升级为拥有文件操作保存联系人信息的通讯录。


  欢迎大家的关注与欣赏!!



未完待续…



C语言实战项目——通讯录3.0已更新