学习了结构体之后,我们就可以尝试实现一个静态版本的通讯录了。

这个通讯录,可以存储1000个人的信息,每个人的信息包括:姓名,年龄,电话,性别,住址;功能包括:1.新增联系人,2.删除联系人,3.查找联系人,4.修改联系人,5.查看所有联系人,6.删除所有联系人,7.对所有联系人进行排序(此版本是最基础的通讯录,后续会出更加全面的升级版本)

一、通讯录菜单

菜单可以实现和用户的交互。那么作为一个通讯录怎么能没有菜单呢?我们第一步先来设计一个菜单选项:

通讯录(静态版本)_#include


二、通讯录主函数

写完了通讯录菜单后,我们就要对主函数进行设计,代码如下:

#include "contact.h"
//为提高对代码阅读者的可读性,这里使用枚举来代替case的0,1,2,3,4,5,6
enum func
{
	Exit,
	add,
	del,
	search,
	modify,
	show,
	del_all,
	sort
};

int main()
{
	int input = 0;
	struct contact_all con_all;
	Init(&con_all);//初始化通讯录
	do
	{
		menu();
		printf("请输入:");
		scanf("%d", &input);
		switch (input)
		{
		case add:
			Add(&con_all);
			break;
		case del:
			Del(&con_all);
			break;
		case search:
			Search(&con_all);
			break;
		case modify:
			Modify(&con_all);
			break;
		case show:
			Show(&con_all);
			break;
		case del_all:
			Del_all(&con_all);
			break;
		case sort:
			Sort(&con_all);
			break;
		case Exit:
			printf("已经退出通讯录了\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

三、枚举主函数内部选

为了增加代码的可读性,我们可以用枚举把1变成add,2变成del ......,这样就不用再回到最上面菜单的地方看每个数字代表什么意思了。


四、定义联系人及通讯录

这一步是为了实现前言中的通讯录内容以及联系人内容,为此我们需要用到结构体

(一)定义联系人内容(结构体)

代码如下:

struct contact_one
{
	char name[20];
	int age;
	char sex[10];
	char tele[20];
	char addr[20];
}con_one;

(二)定义通讯录内容(结构体)

代码如下:

struct contact_all
{
	struct contact_one con_one [max_num];
	int sz;
}con_all;


五、全局变量声明


我们可以#define 一些常量,这样在以后需要修改的时候可以很方便,例如通讯录中联系人的数量.......


六、初始化通讯录

代码如下:

void Init(struct contact_all* pc)
{
	assert(pc);
	pc->sz = 0;
	memset(pc->con_one, 0, sizeof(pc->con_one));
}


七、通过姓名查找函数

代码如下:

void Search(struct contact_all* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("当前通讯录暂无联系人\n");
		return;
	}
	else//根据姓名查找
	{
		char search_name[20] = { 0 };
		printf("请输入要查找的联系人的姓名:");
		scanf("%s", search_name);
		int i = 0;
		for (i = 0; i < pc->sz; i++)
		{
			if (strcmp(search_name, pc->con_one[i].name) == 0)
			{
				printf("找到了:\n");
				printf("%-8s %-4d %-5s %-15s %-10s\n",
					pc->con_one[i].name, pc->con_one[i].age, pc->con_one[i].sex, pc->con_one[i].tele, pc->con_one[i].addr);
				return;
			}
		}
		printf("没有此联系人\n");
	}
}


八、实现通讯录功能

(一)新增联系人

void Add(struct contact_all* pc)
{
	assert(pc);
	if (pc->sz == max_num)
	{
		printf("联系人已满\n");//你怎么那么多联系人?
		return;
	}
	else
	{
		printf("请添加新的联系人的姓名:\n");
		scanf("%s,", pc->con_one[pc->sz].name);
		printf("请添加新的联系人的年龄:\n");
		scanf("%d,", &pc->con_one[pc->sz].age);
		printf("请添加新的联系人的性别:\n");
		scanf("%s,", pc->con_one[pc->sz].sex);
		printf("请添加新的联系人的号码:\n");
		scanf("%s,", pc->con_one[pc->sz].tele);
		printf("请添加新的联系人的地址:\n");
		scanf("%s,", pc->con_one[pc->sz].addr);
		pc->sz++;
		printf("添加成功\n");
	}
}

模拟效果:

通讯录(静态版本)_#include_02


(二)删除联系人

void Del(struct contact_all* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("当前还没有联系人,暂不能进行删除操作\n");
		return;
	}
	else//根据姓名删除
	{
		char del_name[20] = { 0 };
		printf("请输入要删除的联系人的名字:");
		scanf("%s", del_name);
		int i = 0;
		for (i = 0; i<pc->sz; i++)
		{
			if (strcmp(del_name, pc->con_one[i].name) == 0)
			{
				for (i; i < pc->sz - 1; i++)//覆盖
				{
					pc->con_one[i] = pc->con_one[i + 1];
				}
				pc->sz--;
				printf("删除成功\n");
				return;
			}
		}
		printf("没有此联系人\n");
	}
}

模拟效果:

通讯录(静态版本)_初始化_03


(三)查找联系人

void Search(struct contact_all* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("当前通讯录暂无联系人\n");
		return;
	}
	else//根据姓名查找
	{
		char search_name[20] = { 0 };
		printf("请输入要查找的联系人的姓名:");
		scanf("%s", search_name);
		int i = 0;
		for (i = 0; i < pc->sz; i++)
		{
			if (strcmp(search_name, pc->con_one[i].name) == 0)
			{
				printf("找到了:\n");
				printf("%-8s %-4d %-5s %-15s %-10s\n",
					pc->con_one[i].name, pc->con_one[i].age, pc->con_one[i].sex, pc->con_one[i].tele, pc->con_one[i].addr);
				return;
			}
		}
		printf("没有此联系人\n");
	}
}

演示效果:

通讯录(静态版本)_初始化_04


(四)修改联系人

void Modify(struct contact_all* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录没人,无法修改\n");
		return;
	}
	else//根据姓名查找(假设)
	{
		char search_name[20] = { 0 };
		printf("请输入要修改的联系人的姓名:");
		scanf("%s", search_name);
		int i = 0;
		for (i = 0; i < pc->sz; i++)
		{
			if (strcmp(search_name, pc->con_one[i].name) == 0)
			{
				printf("找到了:\n");
				printf("%-8s %-4d %-5s %-15s %-10s\n",
					pc->con_one[i].name, pc->con_one[i].age, pc->con_one[i].sex, pc->con_one[i].tele, pc->con_one[i].addr);
				printf("请修改联系人的姓名:\n");
				scanf("%s,", pc->con_one[i].name);
				printf("请修改联系人的年龄:\n");
				scanf("%d,", &pc->con_one[i].age);
				printf("请修改联系人的性别:\n");
				scanf("%s,", pc->con_one[i].sex);
				printf("请修改联系人的号码:\n");
				scanf("%s,", pc->con_one[i].tele);
				printf("请修改联系人的地址:\n");
				scanf("%s,", pc->con_one[i].addr);
				printf("修改成功\n");
				return;
			}
		}
		printf("没有此联系人\n");
	}
}

演示效果:

通讯录(静态版本)_#include_05


(五)显示所有联系人

void Show(struct contact_all* pc)
{
	assert(pc);
	printf("%-8s %-4s %-5s %-15s %-10s\n", "名字", "年龄", "性别", "电话", "地址");
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-8s %-4d %-5s %-15s %-10s\n",
			pc->con_one[i].name,pc->con_one[i].age,pc->con_one[i].sex,pc->con_one[i].tele,pc->con_one[i].addr);
	}
}

演示效果:

通讯录(静态版本)_初始化_06


(六)按姓名排序所有联系人

int cmp_by_name(const void* e1,const void* e2)
{
	return strcmp(((struct contact_one*)e1)->name,((struct contact_one*)e2)->name);
}

void Sort(struct contact_all* pc)//对名字排序
{
	assert(pc);
	qsort(pc->con_one, pc->sz, sizeof(con_one), cmp_by_name);//快排
	printf("排序完成\n");
}

通讯录(静态版本)_初始化_07


九、头文件

写到这里我们是不是忘记了点什么?没错,那就是头文件,不引用头文件编译器就会报错,所以我们在写代码的时候一定要加上头文件。

代码如下:

#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>


十、完整代码

test.c  :

#include "contact.h"
void menu()
{
	printf("**********************************\n");
	printf("*****  1.add       2.del      ****\n");
	printf("*****  3.search    4.modify   ****\n");
	printf("*****  5.show      6.del_all  ****\n");
	printf("*****  7.sort      0.exit     ****\n");
	printf("**********************************\n");
}
//为提高对代码阅读者的可读性,这里使用枚举来代替case的0,1,2,3,4,5,6
enum func
{
	Exit,
	add,
	del,
	search,
	modify,
	show,
	del_all,
	sort
};

int main()
{
	int input = 0;
	struct contact_all con_all;
	Init(&con_all);//初始化通讯录
	do
	{
		menu();
		printf("请输入:");
		scanf("%d", &input);
		switch (input)
		{
		case add:
			Add(&con_all);
			break;
		case del:
			Del(&con_all);
			break;
		case search:
			Search(&con_all);
			break;
		case modify:
			Modify(&con_all);
			break;
		case show:
			Show(&con_all);
			break;
		case del_all:
			Del_all(&con_all);
			break;
		case sort:
			Sort(&con_all);
			break;
		case Exit:
			printf("已经退出通讯录了\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

contact.h  :

#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#define max_num 1000

struct contact_one
{
	char name[20];
	int age;
	char sex[10];
	char tele[20];
	char addr[20];
}con_one;

struct contact_all
{
	struct contact_one con_one [max_num];
	int sz;
}con_all;

void Init(struct contact_all* pc);//初始化通讯录

void Add(struct contact_all* pc);//增加

void Del(struct contact_all* pc);//删除

void Search(struct contact_all* pc);//查找

void Modify(struct contact_all* pc);//修改

void Del_all(struct contact_all* pc);//清空所有数据

void Sort(struct contact_all* pc);//排序

void Show(struct contact_all* pc);//显示

contact.c  :

#include "contact.h"

void Init(struct contact_all* pc)
{
	assert(pc);
	pc->sz = 0;
	memset(pc->con_one, 0, sizeof(pc->con_one));
}

void Add(struct contact_all* pc)
{
	assert(pc);
	if (pc->sz == max_num)
	{
		printf("联系人已满\n");//你怎么那么多联系人?
		return;
	}
	else
	{
		printf("请添加新的联系人的姓名:\n");
		scanf("%s,", pc->con_one[pc->sz].name);
		printf("请添加新的联系人的年龄:\n");
		scanf("%d,", &pc->con_one[pc->sz].age);
		printf("请添加新的联系人的性别:\n");
		scanf("%s,", pc->con_one[pc->sz].sex);
		printf("请添加新的联系人的号码:\n");
		scanf("%s,", pc->con_one[pc->sz].tele);
		printf("请添加新的联系人的地址:\n");
		scanf("%s,", pc->con_one[pc->sz].addr);
		pc->sz++;
		printf("添加成功\n");
	}
}


void Del(struct contact_all* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("当前还没有联系人,暂不能进行删除操作\n");
		return;
	}
	else//根据姓名删除
	{
		char del_name[20] = { 0 };
		printf("请输入要删除的联系人的名字:");
		scanf("%s", del_name);
		int i = 0;
		for (i = 0; i<pc->sz; i++)
		{
			if (strcmp(del_name, pc->con_one[i].name) == 0)
			{
				for (i; i < pc->sz - 1; i++)//覆盖
				{
					pc->con_one[i] = pc->con_one[i + 1];
				}
				pc->sz--;
				printf("删除成功\n");
				return;
			}
		}
		printf("没有此联系人\n");
	}
}

void Search(struct contact_all* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("当前通讯录暂无联系人\n");
		return;
	}
	else//根据姓名查找
	{
		char search_name[20] = { 0 };
		printf("请输入要查找的联系人的姓名:");
		scanf("%s", search_name);
		int i = 0;
		for (i = 0; i < pc->sz; i++)
		{
			if (strcmp(search_name, pc->con_one[i].name) == 0)
			{
				printf("找到了:\n");
				printf("%-8s %-4d %-5s %-15s %-10s\n",
					pc->con_one[i].name, pc->con_one[i].age, pc->con_one[i].sex, pc->con_one[i].tele, pc->con_one[i].addr);
				return;
			}
		}
		printf("没有此联系人\n");
	}
}

void Modify(struct contact_all* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录没人,无法修改\n");
		return;
	}
	else//根据姓名查找(假设)
	{
		char search_name[20] = { 0 };
		printf("请输入要修改的联系人的姓名:");
		scanf("%s", search_name);
		int i = 0;
		for (i = 0; i < pc->sz; i++)
		{
			if (strcmp(search_name, pc->con_one[i].name) == 0)
			{
				printf("找到了:\n");
				printf("%-8s %-4d %-5s %-15s %-10s\n",
					pc->con_one[i].name, pc->con_one[i].age, pc->con_one[i].sex, pc->con_one[i].tele, pc->con_one[i].addr);
				printf("请修改联系人的姓名:\n");
				scanf("%s,", pc->con_one[i].name);
				printf("请修改联系人的年龄:\n");
				scanf("%d,", &pc->con_one[i].age);
				printf("请修改联系人的性别:\n");
				scanf("%s,", pc->con_one[i].sex);
				printf("请修改联系人的号码:\n");
				scanf("%s,", pc->con_one[i].tele);
				printf("请修改联系人的地址:\n");
				scanf("%s,", pc->con_one[i].addr);
				printf("修改成功\n");
				return;
			}
		}
		printf("没有此联系人\n");
	}
}

int cmp_by_name(const void* e1,const void* e2)
{
	return strcmp(((struct contact_one*)e1)->name,((struct contact_one*)e2)->name);
}

void Sort(struct contact_all* pc)//对名字排序
{
	assert(pc);
	qsort(pc->con_one, pc->sz, sizeof(con_one), cmp_by_name);
	printf("排序完成\n");
}

void Show(struct contact_all* pc)
{
	assert(pc);
	printf("%-8s %-4s %-5s %-15s %-10s\n", "名字", "年龄", "性别", "电话", "地址");
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-8s %-4d %-5s %-15s %-10s\n",
			pc->con_one[i].name,pc->con_one[i].age,pc->con_one[i].sex,pc->con_one[i].tele,pc->con_one[i].addr);
	}
}

void Del_all(struct contact_all* pc)
{
	assert(pc);
	memset(pc->con_one, 0, sizeof(pc->con_one));
	pc->sz = 0;
	printf("已清空所有联系人\n");
	return;
}