掌握结构体的应用-通讯录的实现

系列文章目录


前言

随着信息交流的越来越方便,智能手机现在是必不可少的电子设备,而人们通过电话可以实现和远方的朋友、亲人通话,那么联系人信息是必不可少的,这里将教会你怎么使用通讯录的增、删、查、改等众多功能,请拭目以待!


一、通讯录是什么

通讯录 是存储信息的一种工具,该工具是为了解决联系人查找信息而创建的。

二、通讯录的实现方法

1.引入头文件hearder.h

头文件hearder.h中包括结构体类型的定义和结构体中方法的声明。

1.定义结构体类型 struct PepInfo

结构体PepInfo包含一个人的基本信息。
代码如下:

struct PeoInfo //定义一个结构体人,其中结构体包括人的基本信息
{
	char name[NAME_MAX];  //名字
	int age;              //年龄
	char sex[SEX_MAX];   //性别
	char tel[TEL_MAX];  //电话
	char addr[ADDR_MAX]; //地址
};
2.定义通讯录结构体类型 struct Contact

结构体struct Contact包含数组和人的个数
代码如下:

struct Contact //通讯录的结构体
{
	struct PeoInfo data[MAX];//创建一个数组存放人的信息
	int sz;  //定义通讯录中当前存放人的信息个数
};

2.引入测试文件test.c

测试文件test.c包含各个方法实现方式。

1.初始化通讯录方法InitContact

引用内存函数memset初始化数组内存,其中memset函数的参数形式如下图:
在这里插入图片描述

代码如下:

void InitContact(struct Contact* pc) //初始化通讯录
{
	pc->sz = 0;//通讯录中人的数量先初始化为0
	memset(pc->data, 0, sizeof(pc->data));//数组内存变为0,数组初始化
}
2.增加通讯录成员信息AddContact

首先判断通讯录的人数数量是否达到最大值,如果没有,则加入成员信息。
代码如下:

void AddContact(struct Contact* pc) //增加通讯录信息
{
	if (pc->sz == MAX)
	{
		printf("通讯录已满,无法加入信息!\n");
	}
	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].tel);
		printf("请输入住址:>");
		scanf("%s", pc->data[pc->sz].addr);
		pc->sz++;
		printf("添加成功!\n");
	}
}
3.显示通讯录成员信息ShowContact

根据ShowContact函数可以把通讯录中成员信息打印在屏幕上。
代码如下:

void ShowContact(struct Contact* pc) //显示通讯录中信息
{
	int i = 0;
	printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10s\n", "名字", "年龄", "性别", "电话", "住址");  //打印标题,其中中间的数字是空间可以有15个字符
	if (pc->sz == 0)
	{
		printf("通讯录为空哦,赶紧去加个人吧!\n");
	}
	else
	{
		for (i = 0; i < pc->sz; i++)//其中-10中负号左对齐和10代表域宽
		{
			printf("%-10s\t%-10d\t%-10s\t%-10s\t%-10s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tel, pc->data[i].addr);
		}
	}
}
3.查找通讯录成员名字下标FindByName

用strcmp函数来比较名字的字符是否相同来查找所对应的下标。
代码如下:

static int FindByName(struct Contact* pc,char name[] ) //按名字查找,static修饰函数,只能在自己所在的范围才能使用
{
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;//如果名字相同,则返回所在下标传递回去
		}
	}
	return -1;
}
4.删除通讯录成员信息DelContact

根据查找函数查找通讯录成员名字来删除所对应的信息。
代码如下:

void DelContact(struct Contact* pc)  //删除联系人信息
{
	char name[NAME_MAX] = { 0 };
	if (pc->sz == 0)
	{
		printf("通讯录为空啊,不能删除哦!\n");
	}
	else
	{
		printf("请输入你要删除人的名字:>");
		scanf("%s", name);
		int pos = FindByName(pc, name);
		if (1 == pos)
		{
			printf("删除人的信息不存在!\n");
		}
		else
		{
			int j = 0;
			for (j = pos; j < pc->sz-1; j++) //pc->sz会造成指针越界
			{
				pc->data[j] = pc->data[j + 1];
			}
			pc->sz--;
			printf("删除成功啦!\n");
		}
	}
}
5.查找通讯录成员信息SearchContact

同样调用FindName函数找到对应名字的下标然后打印出来。
代码如下:

void SearchContact(struct Contact* pc) //查找联系人信息
{
	char name[NAME_MAX] = { 0 };
	printf("请输入你要查找人的名字:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (-1 == pos)
	{
		printf("查找的人信息不存在!\n");
	}
	else
	{
		printf("%-10s\t%-10s\t%-10s\t%-10s\t%-10s\n", "名字", "年龄", "性别", "电话", "住址");
		printf("%-10s\t%-10d\t%-10s\t%-10s\t%-10s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex, pc->data[pos].tel, pc->data[pos].addr);
	}
}
6.修改通讯录成员信息SearchContact

同样调用FindName函数找到对面名字下标来修改成员信息。
代码如下:

void ModifyContact(struct Contact* pc) //修改联系人的信息
{
	char name[NAME_MAX] = { 0 };
	printf("请输入要修改人的名字:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (-1 == pos)
	{
		printf("修改人的信息不存在!\n");
	}
	else
	{
		printf("请输入名字:>");
		scanf("%s", pc->data[pos].name);
		printf("请输入年龄:>");
		scanf("%d", &pc->data[pos].age);
		printf("请输入性别:>");
		scanf("%s", pc->data[pos].sex);
		printf("请输入电话:>");
		scanf("%s", pc->data[pos].tel);
		printf("请输入住址:>");
		scanf("%s", pc->data[pos].addr);
		printf("修改成功!\n");
	}
}
7.通讯录成员信息排序SortContact

用qsort函数对任何类型成员数据的信息排序,其中qsort实现方法如下图:
在这里插入图片描述
代码如下:

static int Cmp_ByName(void* p1, void* p2)
{
	return strcmp(((struct PeoInfo*)p1)->name, ((struct PeoInfo*)p2)->name);
}

//交换两个元素的内容(width,是一个元素所占内存空间的大小,单位是字节)
static void Swap(void* p1, void* p2, int width)
{
	//一个字节一个字节的交换
	while (width)
	{
		char tmp = *(char*)p1;
		*(char*)p1 = *(char*)p2;
		*(char*)p2 = tmp;
		++(char*)p1;
		++(char*)p2;
		width--;
	}
}

static void qsort(void* p, int sz, int width, int(*cmp)(void*, void*))
{
	int i = 0;
	int j = 0;
	int flag = 1;//flag为1是是已经排好序,为0是是还没排好序,先默认它为1
	//冒泡排序
	for (i = 0; i < sz - 1; i++)//sz个元素,一共要比较sz-1趟,每一趟排序好一个元素
	{
		for (j = 0; j < sz - 1 - i; j++)//每趟要两两比较当前未排好序的元素个数-1次
		{
			if (cmp((char*)p + (j*width), (char*)p + ((j + 1)*width)) > 0)//判断是否要交换两个元素(既判断前一个元素的名字是否大于后一个元素的名字)
			{
				Swap((char*)p + (j*width), (char*)p + ((j + 1)*width), width);//交换两个成员的位置
				flag = 0;//已经判断这次是无序了,所以flag=0
			}
		}
		if (flag == 1)//若一趟两两比较下来flag仍然=1,则数组肯定有序了,跳出冒泡排序
		{
			break;
		}
	}
}
8.清空通讯录中成员信息ClearContact

调用初始化函数来清空成员信息。
代码如下:

void ClearContact(struct Contact* pc)
{
	InitContact(pc);
	printf("清空通讯录成功!\n");
}

3.引入主文件main.c

1.枚举定义方法的编号

代码如下:

enum option{  //枚举初始化从零开始
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW,
	SORT,
	CLEAR
};
2.打印菜单

代码如下:

void menu()
{
	printf("*************************************\n");
	printf("********* 1.add     2.del    ********\n");
	printf("********* 3.search  4.modify ********\n");
	printf("********* 5.show    6.sort   ********\n");
	printf("********* 0.exit    7.clear  ********\n");
	printf("*************************************\n");
}
3.主文件的实现

代码如下:

void test()
{
	int input = 0;
	struct Contact con;//创建一个通讯录con
	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 SHOW:
			ShowContact(&con);
			break;
		case SORT:
			SortContact(&con);
			ShowContact(&con);
			break;
		case CLEAR:
			ClearContact(&con);
			break;
		case EXIT:
			printf("退出通讯录!\n");
			break;
		default:
			printf("输入的有错误,请重新输入\n");
			break;
		}
	} while (input);
}
int main()
{
	test();
	return 0;
}

二、通讯录的实现方法

结果图的部分显示:
在这里插入图片描述

总结

以上就是通讯录所包括的内容,本文仅仅简单介绍了通讯录的使用,通过通讯录成员信息的增、删、查、改等功能实现了一个简单的通讯录,如果上述有任何问题,请懂哥指教,不过没关系,主要是自己能坚持,更希望有一起学习的同学可以帮我指正,但是如果可以请温柔一点跟我讲,爱与和平是永远的主题,爱各位了。
在这里插入图片描述

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

森明帮大于黑虎帮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值