前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C语言实战小项目——通讯录2.0

C语言实战小项目——通讯录2.0

作者头像
RAIN7
发布2021-08-11 16:30:14
1K0
发布2021-08-11 16:30:14
举报

动态通讯录的实现

——接上篇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.页面菜单

代码语言:javascript
复制
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.通讯录的主体框架实现

代码语言:javascript
复制
//将菜单的功能一一列举出来,以枚举的类型呈现
enum
{
	EXIT,
	ADD,
	DEL,
	MODIFY,
	SEARCH,
	SHOW,
};

int main()
{
	int input = 0;
	//创建通讯录
	struct Contact con;  //Con就是通讯录,里面包含1000个人的信息,及size

	InitContact(&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.通讯录初始化及个人信息的表示

代码语言:javascript
复制
#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)
{
	ps->date = (struct PeoInfor *)malloc(DEFAULT_SZ * sizeof(struct PeoInfor));
	if (ps->date == NULL)
	{
		printf("通讯录初始化失败");
		exit(1);
	}
	ps->size = 0;
	ps->capacity = 2;
}

二、功能函数的具体实现

1.增加联系人的信息

代码语言:javascript
复制
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.删除联系人的信息

代码语言:javascript
复制
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.修改联系人的信息

代码语言:javascript
复制
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.查找联系人的信息

代码语言:javascript
复制
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.展示通讯录联系人信息

代码语言:javascript
复制
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 通讯录主体框架测试文件

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS 1

#include 
#include "contact.h"
#include 

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个人的信息,及size

	InitContact(&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 通讯录函数文件

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS 1
#include 
#include 
#include "contact.h"
#include 

//静态通讯录的信息初始化
//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 宏定义及函数声明文件

代码语言:javascript
复制
#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已更新

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-03-25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 动态通讯录的实现
    • 一.通讯录的各项功能及主体框架
      • 1.通讯录的要求实现功能
        • 2.页面菜单
          • 3.通讯录的主体框架实现
            • 4.通讯录初始化及个人信息的表示
              • 二、功能函数的具体实现
                • 1.增加联系人的信息
                  • 2.删除联系人的信息
                    • 3.修改联系人的信息
                      • 4.查找联系人的信息
                        • 5.展示通讯录联系人信息
                        • 整体代码展示
                          • 1.test.c 通讯录主体框架测试文件
                            • 2.contact.c 通讯录函数文件
                              • 3.contact.h 宏定义及函数声明文件
                              • 小结
                              • 未完待续…
                              相关产品与服务
                              对象存储
                              对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
                              领券
                              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档