C语言:通讯录实现

停步小憩,且闻花香。

                                                                                  ---------《寻找天堂》

目录

文章目录

 一、通讯录介绍

二、  通讯录的实现过程:

 2.1 通讯录的菜单栏

 2.2 定义人的信息(定义存储个人信息的结构体)

2.3 定义通讯录的信息

 2.4 创建通讯录并且初始化

 2.5 添加联系人的信息

2.6 显示通讯录的信息

 2.7 删除联系人的信息

​编辑

 2.8 查找联系人的信息

 2.9 修改联系人的信息

2.10  排序联系人的信息—按名字排序

2.11  销毁通讯录

 三、完整代码

  contact.h

contact.c

test.c


 一、通讯录介绍

        通讯录是记录和存储联系人信息的电子或纸质文件,用于方便用户查找和联系他人。小时候见过的纸质通讯录,是一个小本子,用户可以手动在其中写下联系人的姓名、电话号码、地址等信息。本篇文章介绍这种通讯录的电子版本。这个电子版本的通讯录实现以下功能:

可以保存100个人的信息                                    人的信息:

        1.添加联系人信息;                                    名字

        2.删除联系人信息;                                    年龄

        3.查找联系人信息;                                    电话

        4.修改联系人信息;                                    地址

        5.显示联系人信息;                                    性别

        6.排序联系人信息;

        0.退出程序 

二、  通讯录的实现过程:

         这里将通讯录分为三个模块实现:

                test.c用于测试通讯录功能

                contact.c用于实现通讯录具体功能

                contact.h用于实现接口的声明

 2.1 通讯录的菜单栏

void menu()
{
	printf("***************菜单****************\n");
	printf("****** 1.add        2.del    ******\n");
	printf("****** 3.search     4.modify ******\n");
	printf("****** 5.sort       6.show   ******\n");
	printf("****** 0.exit                ******\n");
	printf("***********************************\n");


}

C语言:通讯录实现_第1张图片

        用户选项 ,进行对应功能的选择,此处使用了枚举,让选项更加清晰易懂

enum Option
{
    EXIT,
    ADD,
    DEL,
    SEARCH,
    MODIFY,
    SORT,
    SHOW
};

        当用户输入对应的选项时,执行对应的功能,使用选择结构进行控制

void test()
{
	int input = 0;
	do
	{
		menu();
		printf("请选择->");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			//增加联系人
			break;
		case DEL:
			//删除联系人
			break;
		case SEARCH:
			//查找联系人
			break;
		case MODIFY:
			//修改联系人
			break;
		case SORT:
			//对通讯录进行排序(按名字)
			break;
		case SHOW:
			//显示联系人
			break;
		case EXIT:
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,请重新选择!\n");
			break;
		}

	} while (input);
}

 2.2 定义人的信息(定义存储个人信息的结构体)

#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 30
#define NUMBER_MAX 12
#define DEFAULT_SZ 3


typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char number[NUMBER_MAX];
	char adress[ADDR_MAX];
	char sex[SEX_MAX];
}PeoInfo;

        画图展示人的信息的结构体如下,比较形象地展示

 C语言:通讯录实现_第2张图片

2.3 定义通讯录的信息

         通讯录不能只存储一个人的信息吧,所以这里还需要定义一个通讯录的结构体,来存储更多人的信息,这里用单链表的结构把每个人的信息连接起来,通过下面的图,比较清晰地展示一下

C语言:通讯录实现_第3张图片

typedef struct Contact
{
	PeoInfo* data;//存放数据
	int capacity;//当前通讯录容量
	int sz;//实际有效信息数量
}Contact;

 2.4 创建通讯录并且初始化

         通讯录的信息已经在contact.h定义好,我们需要在test.c创建并且给它初始化

C语言:通讯录实现_第4张图片

//初始化通讯录
void InitContact(Contact* pc)
{
	assert(pc);  //不能传递空指针,强制断言
	pc->sz = 0;  //通讯录的有效信息数量置0

    //#define DEFAULT_SZ 3 在contact.h定义了,默认存储3个人的信息
	PeoInfo *tmp = (PeoInfo*)malloc(DEFAULT_SZ *sizeof(PeoInfo)); //开空间  
	if (tmp != NULL)
	{
		pc->data = tmp;
	}
	else   //如果malloc开空间失败,打印错误信息,一般不会
	{
		printf("InitContact()::%s\n", strerror(errno)); 
		return;
	}
	pc->capacity = DEFAULT_SZ;  //当前通讯录容量
}

        通讯录初始化后, 运行看看,发现PeoInfo里的数据为随机值,这里只是开了空间,没有初始化里面的数据

 2.5 添加联系人的信息

//增加联系人
void AddContact(Contact* pc)
{	
	assert(pc);
	int i=addcapacity(pc);
	if (i)
	{
		printf("请输入姓名->");
		scanf("%s", pc->data[pc->sz].name);
		printf("请输入性别->");
		scanf("%s", pc->data[pc->sz].sex);
		printf("请输入年龄->");
		scanf("%d", &(pc->data[pc->sz].age));
		printf("请输入住址->");
		scanf("%s", pc->data[pc->sz].adress);
		printf("请输入电话->");
		scanf("%s", pc->data[pc->sz].number);
		pc->sz++;
		printf("添加联系人成功!\n");
	}
	else
	{
		printf("AddContact::%s\n", strerror(errno));
	}
	
}

         由于初始通讯录的时候,默认存储三个人的信息,随着通讯录里面的联系人不断增加,必然会超出这个默认值,所以此时通讯录需要进行扩容

//判断是否增容
int  addcapacity(Contact* pc)
{
	assert(pc);
    //判断一下通讯录是否满了
	if (pc->sz == pc->capacity)  //满了进行扩容
	{                             //relloc扩容后会复制原来的数据,一次加两个人的空间
		PeoInfo* tmp = (PeoInfo*)realloc(pc->data, sizeof(PeoInfo)*(pc->capacity+ 2));
		if (tmp != NULL)
		{
			pc->data = tmp;
			pc->capacity += 2;
			//printf("增容成功\n");
			return 1;
		}
		else
		{
			
			printf("addcapacity()::%s\n", strerror(errno));
			return 0;
		}
	}
	return 1;
	
}

2.6 显示通讯录的信息

         添加完联系人后,想查看里面到目前为止存了哪些联系人,所以需要一个展示通讯录的功能

void ShowContact(Contact* pc)//显示通讯录
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录里无联系人!\n");
	}
	else
	{
		int i = 0;
		printf("%-7s\t%-7s\t%-6s\t%-20s\t%-15s\n", "姓名", "性别", "年龄", "住址", "电话");
		for (i = 0; i < pc->sz; i++)
		{
			printf("%-7s\t%-7s\t%-6d\t%-20s\t%-15s\n",
				pc->data[i].name, pc->data[i].sex, pc->data[i].age,
				pc->data[i].adress, pc->data[i].number);
		}
	}
}

C语言:通讯录实现_第5张图片

 2.7 删除联系人的信息

        删除联系人的步骤,先找到该联系人是否存在,不存在则不执行删除操作,并打印“没有找到您需要删除的人!”;存在则返回该联系人对应的下标 ,删除程序拿到这个下标,从后往前进行覆盖,那么这个联系人就不存在 ====> 被删除啦

int FindPeoInfo(char* name, Contact* pc)//查找联系人,返回其下标
{
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (*name == *(pc->data[i].name))
		{
			return i;
		}
	}
	return -1;
}

void DeleteContact(Contact* pc)//删除联系人
{
	char name[NAME_MAX] = "0";
	int i = 0;
	printf("请输入要删除的联系人姓名->");
	scanf("%s", name);
	//查找联系人
	int flag=FindPeoInfo(name,pc);
	if (flag != -1)
	{
		for (i = flag; i < pc->sz-1; i++)
		{
			pc->data[i] = pc->data[i + 1];
		}
		pc->sz--;
		printf("删除成功!\n");
	}
	else
	{
		printf("没有找到您需要删除的人!\n");
	}
}

C语言:通讯录实现_第6张图片

 2.8 查找联系人的信息

        查找联系人的信息的思路:先查找出来 再打印出来

void FindContact(Contact* pc)//查找联系人
{
	char name[NAME_MAX] = "0";
	printf("请输入要查找的联系人姓名->");
	scanf("%s", name);
	int flag = FindPeoInfo(name, pc);
	if (flag != -1)
	{
		printf("%-7s\t%-7s\t%-6s\t%-20s\t%-15s\n", "姓名", "性别", "年龄", "住址", "电话");
 
		printf("%-7s\t%-7s\t%-6d\t%-20s\t%-15s\n",
			pc->data[flag].name, pc->data[flag].sex, pc->data[flag].age,
			pc->data[flag].adress, pc->data[flag].number);
	}
	else
	{
		printf("查无此人!\n");
	}
}

C语言:通讯录实现_第7张图片

 2.9 修改联系人的信息

         修改联系人的信息的思路跟查找联系人的信息的思路,差不多:先查找出来 再进行修改

void ModifyContact(Contact* pc)//修改联系人
{
	char name[NAME_MAX] = "0";
	printf("请输入要修改的联系人姓名->");
	scanf("%s", name);
	int flag = FindPeoInfo(name, pc);
	if (flag == -1)
	{
		printf("查无此人\n");
		return;
	}
	else
	{
		int input = 0;
		do
		{
			/*char rename[NAME_MAX] = "0";
			int reage = 0;
			char resex[] = "0";
			char readdress[] = "0";
			char*/
			printf("1.姓名  2.年龄  3.性别  4.住址  5.电话  0.退出\n");
			printf("请输入要修改的选项(按0退出修改)->");
			scanf("%d", &input);
			switch (input)
			{
				case 1:
				
					printf("请输入改正后的姓名->");
					scanf("%s", pc->data[flag].name);
					break;
				case 2:
					printf("请输入改正后的年龄->");
					scanf("%d", &(pc->data[flag].age));
					break;
				case 3:
					printf("请输入改正后的性别->");
					scanf("%s", pc->data[flag].sex);
					break;
				case 4:
					printf("请输入改正后的住址->");
					scanf("%s", pc->data[flag].adress);
					break;
				case 5:
					printf("请输入改正后的电话->");
					scanf("%s", pc->data[flag].number);
					break;
				case 0:
					break;
				default:
					printf("输入错误,请重新输入!\n");
					break;
			}
		} while(input);
		printf("修改成功!\n");
	}
 
}

C语言:通讯录实现_第8张图片

2.10  排序联系人的信息—按名字排序

//对联系人进行排序(按名字)
int compare_Peo(const void* e1, const void* e2)
{
	return strcmp(((PeoInfo*)e1)->name,((PeoInfo*)e2)->name);
}


void SortContact(Contact* pc)
{
	qsort(pc->data, pc->sz, sizeof(pc->data[0]), compare_Peo);
	printf("排序成功\n");
	ShowContact(pc);
}

C语言:通讯录实现_第9张图片

2.11  销毁通讯录

         由于通讯录建立中开辟了空间,为了避免内存泄漏,在退出通讯录之前,需要释放开辟的空间

void DestroyContact(Contact* pc)//空间销毁
{
	
	free(pc->data);
	pc->data = NULL;
	pc->capacity = 0;
	pc->sz = 0;
}

C语言:通讯录实现_第10张图片

 三、完整代码

  contact.h

#define _CRT_SECURE_NO_WARNINGS 
#include
#include
#include
#include 
//#define MAX_SIZE 10
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 30
#define NUMBER_MAX 12
#define DEFAULT_SZ 3


typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char number[NUMBER_MAX];
	char adress[ADDR_MAX];
	char sex[SEX_MAX];
}PeoInfo;

typedef struct Contact
{
	PeoInfo* data;//存放数据
	int capacity;//当前通讯录容量
	int sz;//实际有效信息数量
}Contact;

void InitContact(Contact* pc);//初始化通讯录

void AddContact(Contact* pc);//增加联系人
void ShowContact(Contact* pc);//显示通讯录
void DeleteContact(Contact* pc);//删除联系人
int FindPeoInfo(char* name, Contact* pc);//查找联系人,返回其下标
void FindContact(Contact* pc);//查找联系人
void ModifyContact(Contact* pc);//修改联系人
void SortContact(Contact* pc);//对联系人进行排序(按名字)
int addcapacity(Contact* pc);//增容
void DestroyContact(Contact* pc);//销毁通讯录

contact.c

#include"contact.h"
 
//初始化通讯录
void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	PeoInfo *tmp = (PeoInfo*)malloc(DEFAULT_SZ *sizeof(PeoInfo));
	if (tmp != NULL)
	{
		pc->data = tmp;
	}
	else
	{
		printf("InitContact()::%s\n", strerror(errno));
		return;
	}
	pc->capacity = DEFAULT_SZ;
}

//判断是否增容
int  addcapacity(Contact* pc)
{
	assert(pc);
	if (pc->sz == pc->capacity)
	{
		PeoInfo* tmp = (PeoInfo*)realloc(pc->data, sizeof(PeoInfo)*(pc->capacity+ 2));
		if (tmp != NULL)
		{
			pc->data = tmp;
			pc->capacity += 2;
			//printf("增容成功\n");
			return 1;
		}
		else
		{
			
			printf("addcapacity()::%s\n", strerror(errno));
			return 0;
		}
	}
	return 1;
	
}

//增加联系人
void AddContact(Contact* pc)
{	
	assert(pc);
	int i=addcapacity(pc);
	if (i)
	{
		printf("请输入姓名->");
		scanf("%s", pc->data[pc->sz].name);
		printf("请输入性别->");
		scanf("%s", pc->data[pc->sz].sex);
		printf("请输入年龄->");
		scanf("%d", &(pc->data[pc->sz].age));
		printf("请输入住址->");
		scanf("%s", pc->data[pc->sz].adress);
		printf("请输入电话->");
		scanf("%s", pc->data[pc->sz].number);
		pc->sz++;
		printf("添加联系人成功!\n");
	}
	else
	{
		printf("AddContact::%s\n", strerror(errno));
	}
	
}
void ShowContact(Contact* pc)//显示通讯录
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录里无联系人!\n");
	}
	else
	{
		int i = 0;
		printf("%-7s\t%-7s\t%-6s\t%-20s\t%-15s\n", "姓名", "性别", "年龄", "住址", "电话");
		for (i = 0; i < pc->sz; i++)
		{
			printf("%-7s\t%-7s\t%-6d\t%-20s\t%-15s\n",
				pc->data[i].name, pc->data[i].sex, pc->data[i].age,
				pc->data[i].adress, pc->data[i].number);
		}
	}
}
int FindPeoInfo(char* name, Contact* pc)//查找联系人,返回其下标
{
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (*name == *(pc->data[i].name))
		{
			return i;
		}
	}
	return -1;
}
 
void DeleteContact(Contact* pc)//删除联系人
{
	char name[NAME_MAX] = "0";
	int i = 0;
	printf("请输入要删除的联系人姓名->");
	scanf("%s", name);
	//查找联系人
	int flag=FindPeoInfo(name,pc);
	if (flag != -1)
	{
		for (i = flag; i < pc->sz-1; i++)
		{
			pc->data[i] = pc->data[i + 1];
		}
		pc->sz--;
		printf("删除成功!\n");
	}
	else
	{
		printf("没有找到您需要删除的人!\n");
	}
}
void FindContact(Contact* pc)//查找联系人
{
	char name[NAME_MAX] = "0";
	printf("请输入要查找的联系人姓名->");
	scanf("%s", name);
	int flag = FindPeoInfo(name, pc);
	if (flag != -1)
	{
		printf("%-7s\t%-7s\t%-6s\t%-20s\t%-15s\n", "姓名", "性别", "年龄", "住址", "电话");
 
		printf("%-7s\t%-7s\t%-6d\t%-20s\t%-15s\n",
			pc->data[flag].name, pc->data[flag].sex, pc->data[flag].age,
			pc->data[flag].adress, pc->data[flag].number);
	}
	else
	{
		printf("查无此人!\n");
	}
}
 
void ModifyContact(Contact* pc)//修改联系人
{
	char name[NAME_MAX] = "0";
	printf("请输入要修改的联系人姓名->");
	scanf("%s", name);
	int flag = FindPeoInfo(name, pc);
	if (flag == -1)
	{
		printf("查无此人\n");
		return;
	}
	else
	{
		int input = 0;
		do
		{
			/*char rename[NAME_MAX] = "0";
			int reage = 0;
			char resex[] = "0";
			char readdress[] = "0";
			char*/
			printf("1.姓名  2.年龄  3.性别  4.住址  5.电话  0.退出\n");
			printf("请输入要修改的选项(按0退出修改)->");
			scanf("%d", &input);
			switch (input)
			{
				case 1:
				
					printf("请输入改正后的姓名->");
					scanf("%s", pc->data[flag].name);
					break;
				case 2:
					printf("请输入改正后的年龄->");
					scanf("%d", &(pc->data[flag].age));
					break;
				case 3:
					printf("请输入改正后的性别->");
					scanf("%s", pc->data[flag].sex);
					break;
				case 4:
					printf("请输入改正后的住址->");
					scanf("%s", pc->data[flag].adress);
					break;
				case 5:
					printf("请输入改正后的电话->");
					scanf("%s", pc->data[flag].number);
					break;
				case 0:
					break;
				default:
					printf("输入错误,请重新输入!\n");
					break;
			}
		} while(input);
		printf("修改成功!\n");
	}
 
}
 
//对联系人进行排序(按名字)
int compare_Peo(const void* e1, const void* e2)
{
	return strcmp(((PeoInfo*)e1)->name,((PeoInfo*)e2)->name);
}

void SortContact(Contact* pc)
{
	qsort(pc->data, pc->sz, sizeof(pc->data[0]), compare_Peo);
	printf("排序成功\n");
	ShowContact(pc);
}

void DestroyContact(Contact* pc)//空间销毁
{
	
	free(pc->data);
	pc->data = NULL;
	pc->capacity = 0;
	pc->sz = 0;
}

test.c

#include"contact.h"
enum Option
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SORT,
	SHOW
};
void menu()
{
	printf("***************菜单****************\n");
	printf("****** 1.add        2.del    ******\n");
	printf("****** 3.search     4.modify ******\n");
	printf("****** 5.sort       6.show   ******\n");
	printf("****** 0.exit                ******\n");
	printf("***********************************\n");


}
void test()
{
	Contact con;
	InitContact(&con);//初始化通讯录
	int input = 0;
	do
	{
		menu();
		printf("请选择->");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			//增加联系人
			AddContact(&con);

			break;
		case DEL:
			//删除联系人
			DeleteContact(&con);
			break;
		case SEARCH:
			//查找联系人
			FindContact(&con);
			break;
		case MODIFY:
			//修改联系人
			ModifyContact(&con);
			break;
		case SORT:
			//对通讯录进行排序(按名字)
			SortContact(&con);
			break;
		case SHOW:
			//显示联系人
			ShowContact(&con);
			break;
		case EXIT:
			DestroyContact(&con);
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,请重新选择!\n");
			break;
		}

	} while (input);
}



int main()
{
	test();
	return 0;
}

         若有不足之处,望各位大佬多多指教

你可能感兴趣的:(c语言,笔记)