【C语言】通讯录

目录

一、关于通讯录

二、代码逻辑

三、通讯录实现

1.菜单设计

2.逻辑主要功能设计

3.增加联系人功能实现

4.显示全部联系人信息 

 5.删除联系人

6.查找联系人

7.修改联系人信息

8.对联系人进行排序

 9.一键清空所有联系人

四、完整源码

test.c

contact.c

contact.h


一、关于通讯录

在通讯录中,我们一般保存联系人的信息,联系人的信息一般会有 姓名、年龄、性别、电话、地址等。在通讯录中,我们也会对一些信息进行增删改查。

二、代码逻辑

代码文件

test.c 用于测试代码

contact.h 用于存放头文件

contact.c 用于主要代码的功能实现

  1. 菜单设计
  2. 功能实现

三、通讯录实现

1.菜单设计

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

2.逻辑主要功能设计

因为有了菜单可以进行功能选择

功能实现的前提是  先对通讯录 进行设计 并 初始化

采用结构体进行设计

typedef struct PeoInfo 
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char tele[TELE_MAX];
	char addr[ADDR_MAX];
}PeoInfo;

typedef struct Contact 
{
	PeoInfo data[MAX];//存放通讯录数据
	int sz;//记录通讯录存了多少个数据
}Contact;

通讯录初始化(使用memset 将通讯录数据置0)

//初始化通讯录
void InitContact(Contact *pc) 
{
	assert(pc);//断言一下,避免空指针
	//将通讯录数据置0
	memset(pc->data,0,sizeof(pc->data)); //这里使用的内存函数,也可以使用for循环进行
	pc->sz = 0;//将记录通讯录信息个数置0
}

采用do ...while 和 switch 进行设计

	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);//对联系人进行排序
			break;
		case CLEAR:
			InitContact(&con);//清空通讯录
			break;
		case EXIT:
			printf("退出通讯录!\n");
			break;
		default:
			Sleep(300);
			system("cls");//清屏
			printf("输入错误,请重新输入!\n");
		}
	} while (input);

在这里我们发现switch 语句中 的case 选项中的常量表达式 是字母,这里主要是利用了枚举常量。

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

EXIT表示0 ,ADD表示1 依次类推... 

这样在switch语句中就增加了代码的可读性和可调试性

3.增加联系人功能实现

//增加联系人
void AddContact(Contact* pc) 
{
	assert(pc);
	//首先应该判断通讯录是否已满
	if (pc->sz == MAX) 
	{
		printf("通讯录已满,无法添加!\n");
		return;
	}

	Sleep(300);
	system("cls");//清屏
	//增加的信息
	//名字 年龄 性别 电话 地址
	printf("----------------------------------------------------------------------------\n");
	printf("-%-20s\t|%-5s\t|%-5s\t|%-12s\t|%-18s-\n","名字","年龄","性别","电话","地址");
	printf("----------------------------------------------------------------------------\n");


	//增加信息
	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].tele);
	printf("请输入地址:");
	scanf("%s", pc->data[pc->sz].addr);
	pc->sz++;
	printf("增加成功\n");
	Sleep(1000);
	system("cls");//清屏
}

4.显示全部联系人信息 

上述是增加联系人的信息,既然增加联系人我们就来查看联系人信息

//显示全部联系人
void ShowContact( const Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空!\n");
		Sleep(1000);
		system("cls");//清屏
		return;
	}
	printf("----------------------------------------------------------------------------\n");
	printf("-%-20s\t|%-5s\t|%-5s\t|%-12s\t|%-18s-\n", "名字", "年龄", "性别", "电话", "地址");
	printf("----------------------------------------------------------------------------\n");
	for (int i = 0; i < pc -> sz;i++)
	{
		printf("%-20s\t|%-5d\t|%-5s\t|%-12s\t|%-30s\n",
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].tele,
			pc->data[i].addr);
	}

}

 5.删除联系人

这里采用的思想是 数组后面的元素前移将前面的元素覆盖来达到删除该信息的目的

这里是删除指定联系人

//按名字查找
static int FindByName(Contact* pc,char name[])
{
	assert(pc);
	int i = 0;
	for (i = 0; i < pc->sz;i++)
	{
		if (strcmp(pc->data[i].name,name) == 0) 
		{
			return i;
		}
	}
	return -1;
}

//删除联系人
void DelContact(Contact* pc) 
{
	assert(pc);
	if (pc->sz == 0) 
	{
		printf("通讯录为空,无法删除!\n");
		Sleep(1000);
		system("cls");//清屏
		return;
	}
	char name[NAME_MAX];
	printf("输入要删除的名字:");
	scanf("%s",&name);
	int ret = FindByName(pc,name);
	if (ret == -1)
	{
		printf("要删除的联系人不存在\n");
		Sleep(1000);
		system("cls");//清屏
		return;
	}
	int i = 0;
	//进行删除的操作
	for (i = ret; i < pc->sz - 1;i++) 
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->sz--;
	printf("删除成功!\n");
	Sleep(1000);
	system("cls");//清屏
}

6.查找联系人

//查找联系人
void SearchContact(Contact* pc) 
{
	assert(pc);
	char name[NAME_MAX];
	Sleep(1000);
	system("cls");//清屏
	printf("请输入要查找人的名字:");
	scanf("%s",name);
	int ret = FindByName(pc, name);
	if (ret == -1)
	{
		printf("要查找的联系人不存在\n");
		//Sleep(1000);
		//system("cls");//清屏
		return;
	}
	Sleep(1000);
	system("cls");//清屏
	//显示出查找的联系人
	printf("----------------------------------------------------------------------------\n");
	printf("-%-20s\t|%-5s\t|%-5s\t|%-12s\t|%-18s-\n", "名字", "年龄", "性别", "电话", "地址");
	printf("----------------------------------------------------------------------------\n");
	printf("%-20s\t|%-5d\t|%-5s\t|%-12s\t|%-18s\n",
			pc->data[ret].name,
			pc->data[ret].age,
			pc->data[ret].sex,
			pc->data[ret].tele,
			pc->data[ret].addr);
	Sleep(3000);
}

7.修改联系人信息

enum option_menu 
{
	EXIT,
	NAME ,
	AGE,
	SEX,
	TELE,
	ADDR
};
//修改联系人信息
void ModifyContact(Contact* pc) 
{
	assert(pc);
	char name[NAME_MAX];
	printf("请输入要修改联系人的名字:");
	scanf("%s",name);
	int ret = FindByName(pc, name);
	if (ret == -1)
	{
		printf("要修改的联系人不存在\n");
		Sleep(1000);
		system("cls");//清屏
		return;
	}

	//修改联系人
	printf("**********\n");
	printf("#1. 名字 *\n#2. 年龄 *\n#3. 性别 *\n#4. 电话 *\n#5. 地址 *\n#0. 返回 *\n");
	printf("**********\n");
	int input = 0;
	do
	{
		//option_menu();
		printf("请选择你要的信息:>\n");
		scanf("%d", &input);
		switch (input)
		{
		case NAME:
			printf("请输入名字:\n");
			scanf("%s", pc->data[ret].name);
			break;
		case AGE:
			printf("请输入年龄:\n");
			scanf("%d", &(pc->data[ret].age));
			break;
		case SEX:
			printf("请输入性别:\n");
			scanf("%s", pc->data[ret].sex);
			break;
		case TELE:
			printf("请输入电话:\n");
			scanf("%s", pc->data[ret].tele);
			break;
		case ADDR:
			printf("请输入地址:\n");
			scanf("%s", pc->data[ret].addr);
			break;
		case EXIT:
			printf("返回主界面\n");
			return;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}

	} while (input);

}

8.对联系人进行排序

int cmp_name(const void* s1,const void* s2) 
{
	return strcmp(((Contact*)s1)->data->name, ((Contact*)s2)->data->name);
}
int cmp_age(const void* s1,const void* s2)
{
	return ((Contact*)s1)->data->age - ((Contact*)s2)->data->age;
}
//排序
void SortContact(Contact* pc) 
{
	assert(pc);
	if (pc->sz == 0) 
	{
		printf("通讯录为空,无法排序 !");
		return;
	}
	int input = 0;
	printf("***********\n");
	printf("# 1. 名字 *\n# 2. 年龄 *\n");
	printf("***********\n");
	printf("请选择排序的方法:");
	scanf("%d",&input);
	if (input == 1) 
	{
		//按名字进行排序
		qsort(pc->data, pc->sz, sizeof(PeoInfo), cmp_name);
		printf("----------------------------------------------------------------------------\n");
		printf("-%-20s\t|%-5s\t|%-5s\t|%-12s\t|%-18s-\n", "名字", "年龄", "性别", "电话", "地址");
		printf("----------------------------------------------------------------------------\n");
		for (int i = 0; i < pc->sz; i++)
		{
			printf("%-20s\t|%-5d\t|%-5s\t|%-12s\t|%-30s\n",
				pc->data[i].name,
				pc->data[i].age,
				pc->data[i].sex,
				pc->data[i].tele,
				pc->data[i].addr);
		}
	}
	else if (input == 2) 
	{
		//按年龄进行排序
		qsort(pc->data, pc->sz, sizeof(PeoInfo), cmp_age);
		printf("----------------------------------------------------------------------------\n");
		printf("-%-20s\t|%-5s\t|%-5s\t|%-12s\t|%-18s-\n", "名字", "年龄", "性别", "电话", "地址");
		printf("----------------------------------------------------------------------------\n");
		for (int i = 0; i < pc->sz; i++)
		{
			printf("%-20s\t|%-5d\t|%-5s\t|%-12s\t|%-30s\n",
				pc->data[i].name,
				pc->data[i].age,
				pc->data[i].sex,
				pc->data[i].tele,
				pc->data[i].addr);
		}
	}
}

先展示一下原来数据的信息

 排序1

排序2

 9.一键清空所有联系人

 这里是直接调用的初始化通讯录函数

//初始化通讯录
void InitContact(Contact *pc) 
{
	assert(pc);//断言一下,避免空指针
	//将通讯录数据置0
	memset(pc->data,0,sizeof(pc->data)); //这里使用的内存函数,也可以使用for循环进行
	pc->sz = 0;//将记录通讯录信息个数置0
}

四、完整源码

test.c

#define _CRT_SECURE_NO_WARNINGS 
//用于测试
#include "contact.h"
void menu() 
{
	printf("***********************************\n");
	printf("****** 1. add      2. del    ******\n");
	printf("****** 3. search   4. modify ******\n");
	printf("****** 5. show     6. sort   ******\n");
	printf("****** 7. clear    0. exit   ******\n");
	printf("***********************************\n");
}
enum Option 
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW,
	SORT,
	CLEAR
};
int main() 
{
	int input = 0;
	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);//对联系人进行排序
			break;
		case CLEAR:
			InitContact(&con);//清空通讯录
			break;
		case EXIT:
			printf("退出通讯录!\n");
			break;
		default:
			Sleep(300);
			system("cls");//清屏
			printf("输入错误,请重新输入!\n");
		}
	} while (input);
	return 0;
}

contact.c

#define _CRT_SECURE_NO_WARNINGS 
#include "contact.h"

//用于实现函数

//初始化通讯录
void InitContact(Contact *pc) 
{
	assert(pc);//断言一下,避免空指针
	//将通讯录数据置0
	memset(pc->data,0,sizeof(pc->data)); //这里使用的内存函数,也可以使用for循环进行
	pc->sz = 0;//将记录通讯录信息个数置0
}

//增加联系人
void AddContact(Contact* pc) 
{
	assert(pc);
	//首先应该判断通讯录是否已满
	if (pc->sz == MAX) 
	{
		printf("通讯录已满,无法添加!\n");
		return;
	}

	Sleep(300);
	system("cls");//清屏
	//增加的信息
	//名字 年龄 性别 电话 地址
	printf("----------------------------------------------------------------------------\n");
	printf("-%-20s\t|%-5s\t|%-5s\t|%-12s\t|%-18s-\n","名字","年龄","性别","电话","地址");
	printf("----------------------------------------------------------------------------\n");


	//增加信息
	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].tele);
	printf("请输入地址:");
	scanf("%s", pc->data[pc->sz].addr);
	pc->sz++;
	printf("增加成功\n");
	Sleep(1000);
	system("cls");//清屏
}

//显示全部联系人
void ShowContact( const Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空!\n");
		Sleep(1000);
		system("cls");//清屏
		return;
	}
	printf("----------------------------------------------------------------------------\n");
	printf("-%-20s\t|%-5s\t|%-5s\t|%-12s\t|%-18s-\n", "名字", "年龄", "性别", "电话", "地址");
	printf("----------------------------------------------------------------------------\n");
	for (int i = 0; i < pc -> sz;i++)
	{
		printf("%-20s\t|%-5d\t|%-5s\t|%-12s\t|%-30s\n",
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].tele,
			pc->data[i].addr);
	}

}
//按名字查找
static int FindByName(Contact* pc,char name[])
{
	assert(pc);
	int i = 0;
	for (i = 0; i < pc->sz;i++)
	{
		if (strcmp(pc->data[i].name,name) == 0) 
		{
			return i;
		}
	}
	return -1;
}

//删除联系人
void DelContact(Contact* pc) 
{
	assert(pc);
	if (pc->sz == 0) 
	{
		printf("通讯录为空,无法删除!\n");
		Sleep(1000);
		system("cls");//清屏
		return;
	}
	char name[NAME_MAX];
	printf("输入要删除的名字:");
	scanf("%s",&name);
	int ret = FindByName(pc,name);
	if (ret == -1)
	{
		printf("要删除的联系人不存在\n");
		Sleep(1000);
		system("cls");//清屏
		return;
	}
	int i = 0;
	//进行删除的操作
	for (i = ret; i < pc->sz - 1;i++) 
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->sz--;
	printf("删除成功!\n");
}

//查找联系人
void SearchContact(Contact* pc) 
{
	assert(pc);
	char name[NAME_MAX];
	Sleep(1000);
	system("cls");//清屏
	printf("请输入要查找人的名字:");
	scanf("%s",name);
	int ret = FindByName(pc, name);
	if (ret == -1)
	{
		printf("要查找的联系人不存在\n");
		//Sleep(1000);
		//system("cls");//清屏
		return;
	}
	Sleep(1000);
	system("cls");//清屏
	//显示出查找的联系人
	printf("----------------------------------------------------------------------------\n");
	printf("-%-20s\t|%-5s\t|%-5s\t|%-12s\t|%-18s-\n", "名字", "年龄", "性别", "电话", "地址");
	printf("----------------------------------------------------------------------------\n");
	printf("%-20s\t|%-5d\t|%-5s\t|%-12s\t|%-18s\n",
			pc->data[ret].name,
			pc->data[ret].age,
			pc->data[ret].sex,
			pc->data[ret].tele,
			pc->data[ret].addr);
	Sleep(3000);
}


enum option_menu 
{
	EXIT,
	NAME ,
	AGE,
	SEX,
	TELE,
	ADDR
};
//修改联系人信息
void ModifyContact(Contact* pc) 
{
	assert(pc);
	char name[NAME_MAX];
	printf("请输入要修改联系人的名字:");
	scanf("%s",name);
	int ret = FindByName(pc, name);
	if (ret == -1)
	{
		printf("要修改的联系人不存在\n");
		Sleep(1000);
		system("cls");//清屏
		return;
	}

	//修改联系人
	printf("**********\n");
	printf("#1. 名字 *\n#2. 年龄 *\n#3. 性别 *\n#4. 电话 *\n#5. 地址 *\n#0. 返回 *\n");
	printf("**********\n");
	int input = 0;
	do
	{
		//option_menu();
		printf("请选择你要的信息:>\n");
		scanf("%d", &input);
		switch (input)
		{
		case NAME:
			printf("请输入名字:\n");
			scanf("%s", pc->data[ret].name);
			break;
		case AGE:
			printf("请输入年龄:\n");
			scanf("%d", &(pc->data[ret].age));
			break;
		case SEX:
			printf("请输入性别:\n");
			scanf("%s", pc->data[ret].sex);
			break;
		case TELE:
			printf("请输入电话:\n");
			scanf("%s", pc->data[ret].tele);
			break;
		case ADDR:
			printf("请输入地址:\n");
			scanf("%s", pc->data[ret].addr);
			break;
		case EXIT:
			printf("返回主界面\n");
			return;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}

	} while (input);

}



int cmp_name(const void* s1,const void* s2) 
{
	return strcmp(((Contact*)s1)->data->name, ((Contact*)s2)->data->name);
}
int cmp_age(const void* s1,const void* s2)
{
	return ((Contact*)s1)->data->age - ((Contact*)s2)->data->age;
}
//排序
void SortContact(Contact* pc) 
{
	assert(pc);
	if (pc->sz == 0) 
	{
		printf("通讯录为空,无法排序 !");
		return;
	}
	int input = 0;
	printf("***********\n");
	printf("# 1. 名字 *\n# 2. 年龄 *\n");
	printf("***********\n");
	printf("请选择排序的方法:");
	scanf("%d",&input);
	if (input == 1) 
	{
		//按名字进行排序
		qsort(pc->data, pc->sz, sizeof(PeoInfo), cmp_name);
		printf("----------------------------------------------------------------------------\n");
		printf("-%-20s\t|%-5s\t|%-5s\t|%-12s\t|%-18s-\n", "名字", "年龄", "性别", "电话", "地址");
		printf("----------------------------------------------------------------------------\n");
		for (int i = 0; i < pc->sz; i++)
		{
			printf("%-20s\t|%-5d\t|%-5s\t|%-12s\t|%-30s\n",
				pc->data[i].name,
				pc->data[i].age,
				pc->data[i].sex,
				pc->data[i].tele,
				pc->data[i].addr);
		}
	}
	else if (input == 2) 
	{
		//按年龄进行排序
		qsort(pc->data, pc->sz, sizeof(PeoInfo), cmp_age);
		printf("----------------------------------------------------------------------------\n");
		printf("-%-20s\t|%-5s\t|%-5s\t|%-12s\t|%-18s-\n", "名字", "年龄", "性别", "电话", "地址");
		printf("----------------------------------------------------------------------------\n");
		for (int i = 0; i < pc->sz; i++)
		{
			printf("%-20s\t|%-5d\t|%-5s\t|%-12s\t|%-30s\n",
				pc->data[i].name,
				pc->data[i].age,
				pc->data[i].sex,
				pc->data[i].tele,
				pc->data[i].addr);
		}
	}
}

contact.h

#pragma once

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

#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30

#define MAX 1000 //用于存放通信录信息的条数
//用于声明函数

typedef struct PeoInfo 
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char tele[TELE_MAX];
	char addr[ADDR_MAX];
}PeoInfo;

typedef struct Contact 
{
	PeoInfo data[MAX];//存放通讯录数据
	int sz;//记录通讯录存了多少个数据
}Contact;

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

//增加联系人
void AddContact(Contact* pc);

//显示全部联系人
void ShowContact(Contact* pc);

//删除联系人
void DelContact(Contact* pc);

//查找联系人
void SearchContact(Contact* pc);

//修改联系人信息
void ModifyContact(Contact* pc);

//排序
void SortContact(Contact* pc);

五、动态增容版本

因为上方的功能只能 对固定通讯录的人数进行增删改查,所以对上方代码进行增加使用了calloc、realloc等动态内存函数。来使通讯录的容量可以进行动态的变更

直接上源码

test.c

#define _CRT_SECURE_NO_WARNINGS 
//用于测试
#include "contact.h"
void menu() 
{
	printf("***********************************\n");
	printf("****** 1. add      2. del    ******\n");
	printf("****** 3. search   4. modify ******\n");
	printf("****** 5. show     6. sort   ******\n");
	printf("****** 7. clear    0. exit   ******\n");
	printf("***********************************\n");
}
enum Option 
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW,
	SORT,
	CLEAR
};
int main() 
{
	int input = 0;
	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);//对联系人进行排序
			break;
		case CLEAR:
			InitContact(&con);//清空通讯录
			break;
		case EXIT:
			DestoryContact(&con);
			printf("退出通讯录!\n");
			break;
		default:
			Sleep(300);
			system("cls");//清屏
			printf("输入错误,请重新输入!\n");
		}
	} while (input);
	return 0;
}

contact.c

#define _CRT_SECURE_NO_WARNINGS 
#include "contact.h"

//用于实现函数

//初始化通讯录
//静态版本
//void InitContact(Contact *pc) 
//{
//	assert(pc);//断言一下,避免空指针
//	//将通讯录数据置0
//	memset(pc->data,0,sizeof(pc->data)); //这里使用的内存函数,也可以使用for循环进行
//	pc->sz = 0;//将记录通讯录信息个数置0
//}
void InitContact(Contact *pc) 
{
	assert(pc);//断言一下,避免空指针
	pc->sz = 0;
	pc->capacity = DEFAULT_SZ;
	pc->data = calloc(pc->capacity,sizeof(PeoInfo));
	if (pc->data == NULL) 
	{
		perror("InitContact->calloc");
		return;
	}
}

//增加联系人.静态版本
//void AddContact(Contact* pc) 
//{
//	assert(pc);
//	//首先应该判断通讯录是否已满
//	if (pc->sz == MAX) 
//	{
//		printf("通讯录已满,无法添加!\n");
//		return;
//	}
//
//	Sleep(300);
//	system("cls");//清屏
//	//增加的信息
//	//名字 年龄 性别 电话 地址
//	printf("----------------------------------------------------------------------------\n");
//	printf("-%-20s\t|%-5s\t|%-5s\t|%-12s\t|%-18s-\n","名字","年龄","性别","电话","地址");
//	printf("----------------------------------------------------------------------------\n");
//
//
//	//增加信息
//	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].tele);
//	printf("请输入地址:");
//	scanf("%s", pc->data[pc->sz].addr);
//	pc->sz++;
//	printf("增加成功\n");
//	Sleep(1000);
//	system("cls");//清屏
//}

void CheckCapacity(Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		PeoInfo* ptr = (PeoInfo*)realloc(pc->data,(pc->capacity+2)*sizeof(PeoInfo));
		if (ptr != NULL) 
		{
			pc->data = ptr;
			pc->capacity+= 2;
			printf("增容成功!");
		}
		else
		{
			perror("AddContact->realloc");
			return;
		}
	}
}
//动态版本
void AddContact(Contact* pc)
{
	assert(pc);
	//增加容量
	CheckCapacity(pc);

	Sleep(300);
	system("cls");//清屏
	//增加的信息
	//名字 年龄 性别 电话 地址
	printf("----------------------------------------------------------------------------\n");
	printf("-%-20s\t|%-5s\t|%-5s\t|%-12s\t|%-18s-\n", "名字", "年龄", "性别", "电话", "地址");
	printf("----------------------------------------------------------------------------\n");


	//增加信息
	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].tele);
	printf("请输入地址:");
	scanf("%s", pc->data[pc->sz].addr);
	pc->sz++;
	printf("增加成功\n");
	Sleep(1000);
	system("cls");//清屏
}

//显示全部联系人
void ShowContact(  const Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空!\n");
		Sleep(1000);
		system("cls");//清屏
		return;
	}
	printf("----------------------------------------------------------------------------\n");
	printf("-%-20s\t|%-5s\t|%-5s\t|%-12s\t|%-18s-\n", "名字", "年龄", "性别", "电话", "地址");
	printf("----------------------------------------------------------------------------\n");
	for (int i = 0; i < pc -> sz;i++)
	{
		printf("%-20s\t|%-5d\t|%-5s\t|%-12s\t|%-30s\n",
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].tele,
			pc->data[i].addr);
	}

}
//按名字查找
static int FindByName(Contact* pc,char name[])
{
	assert(pc);
	int i = 0;
	for (i = 0; i < pc->sz;i++)
	{
		if (strcmp(pc->data[i].name,name) == 0) 
		{
			return i;
		}
	}
	return -1;
}

//删除联系人
void DelContact(Contact* pc) 
{
	assert(pc);
	if (pc->sz == 0) 
	{
		printf("通讯录为空,无法删除!\n");
		Sleep(1000);
		system("cls");//清屏
		return;
	}
	char name[NAME_MAX];
	printf("输入要删除的名字:");
	scanf("%s",&name);
	int ret = FindByName(pc,name);
	if (ret == -1)
	{
		printf("要删除的联系人不存在\n");
		Sleep(1000);
		system("cls");//清屏
		return;
	}
	int i = 0;
	//进行删除的操作
	for (i = ret; i < pc->sz - 1;i++) 
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->sz--;
	printf("删除成功!\n");
}

//查找联系人
void SearchContact(Contact* pc) 
{
	assert(pc);
	char name[NAME_MAX];
	Sleep(1000);
	system("cls");//清屏
	printf("请输入要查找人的名字:");
	scanf("%s",name);
	int ret = FindByName(pc, name);
	if (ret == -1)
	{
		printf("要查找的联系人不存在\n");
		//Sleep(1000);
		//system("cls");//清屏
		return;
	}
	Sleep(1000);
	system("cls");//清屏
	//显示出查找的联系人
	printf("----------------------------------------------------------------------------\n");
	printf("-%-20s\t|%-5s\t|%-5s\t|%-12s\t|%-18s-\n", "名字", "年龄", "性别", "电话", "地址");
	printf("----------------------------------------------------------------------------\n");
	printf("%-20s\t|%-5d\t|%-5s\t|%-12s\t|%-18s\n",
			pc->data[ret].name,
			pc->data[ret].age,
			pc->data[ret].sex,
			pc->data[ret].tele,
			pc->data[ret].addr);
	Sleep(3000);
}


enum option_menu 
{
	EXIT,
	NAME ,
	AGE,
	SEX,
	TELE,
	ADDR
};
//修改联系人信息
void ModifyContact(Contact* pc) 
{
	assert(pc);
	char name[NAME_MAX];
	printf("请输入要修改联系人的名字:");
	scanf("%s",name);
	int ret = FindByName(pc, name);
	if (ret == -1)
	{
		printf("要修改的联系人不存在\n");
		Sleep(1000);
		system("cls");//清屏
		return;
	}

	//修改联系人
	printf("**********\n");
	printf("#1. 名字 *\n#2. 年龄 *\n#3. 性别 *\n#4. 电话 *\n#5. 地址 *\n#0. 返回 *\n");
	printf("**********\n");
	int input = 0;
	do
	{
		//option_menu();
		printf("请选择你要的信息:>\n");
		scanf("%d", &input);
		switch (input)
		{
		case NAME:
			printf("请输入名字:\n");
			scanf("%s", pc->data[ret].name);
			break;
		case AGE:
			printf("请输入年龄:\n");
			scanf("%d", &(pc->data[ret].age));
			break;
		case SEX:
			printf("请输入性别:\n");
			scanf("%s", pc->data[ret].sex);
			break;
		case TELE:
			printf("请输入电话:\n");
			scanf("%s", pc->data[ret].tele);
			break;
		case ADDR:
			printf("请输入地址:\n");
			scanf("%s", pc->data[ret].addr);
			break;
		case EXIT:
			printf("返回主界面\n");
			return;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}

	} while (input);

}



int cmp_name(const void* s1,const void* s2) 
{
	return strcmp(((Contact*)s1)->data->name, ((Contact*)s2)->data->name);
}
int cmp_age(const void* s1,const void* s2)
{
	return ((Contact*)s1)->data->age - ((Contact*)s2)->data->age;
}
//排序
void SortContact(Contact* pc) 
{
	assert(pc);
	if (pc->sz == 0) 
	{
		printf("通讯录为空,无法排序 !");
		return;
	}
	int input = 0;
	printf("***********\n");
	printf("# 1. 名字 *\n# 2. 年龄 *\n");
	printf("***********\n");
	printf("请选择排序的方法:");
	scanf("%d",&input);
	if (input == 1) 
	{
		//按名字进行排序
		qsort(pc->data, pc->sz, sizeof(PeoInfo), cmp_name);
		printf("----------------------------------------------------------------------------\n");
		printf("-%-20s\t|%-5s\t|%-5s\t|%-12s\t|%-18s-\n", "名字", "年龄", "性别", "电话", "地址");
		printf("----------------------------------------------------------------------------\n");
		for (int i = 0; i < pc->sz; i++)
		{
			printf("%-20s\t|%-5d\t|%-5s\t|%-12s\t|%-30s\n",
				pc->data[i].name,
				pc->data[i].age,
				pc->data[i].sex,
				pc->data[i].tele,
				pc->data[i].addr);
		}
	}
	else if (input == 2) 
	{
		//按年龄进行排序
		qsort(pc->data, pc->sz, sizeof(PeoInfo), cmp_age);
		printf("----------------------------------------------------------------------------\n");
		printf("-%-20s\t|%-5s\t|%-5s\t|%-12s\t|%-18s-\n", "名字", "年龄", "性别", "电话", "地址");
		printf("----------------------------------------------------------------------------\n");
		for (int i = 0; i < pc->sz; i++)
		{
			printf("%-20s\t|%-5d\t|%-5s\t|%-12s\t|%-30s\n",
				pc->data[i].name,
				pc->data[i].age,
				pc->data[i].sex,
				pc->data[i].tele,
				pc->data[i].addr);
		}
	}
}

void DestoryContact(Contact* pc) 
{
	free(pc->data);
	pc->data = NULL;
	pc->sz = 0;
	pc->capacity = 0;
}

contact.h 

#pragma once

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

#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30

#define MAX 1000 //用于存放通信录信息的条数

#define DEFAULT_SZ 3//默认值
//用于声明函数

typedef struct PeoInfo 
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char tele[TELE_MAX];
	char addr[ADDR_MAX];
}PeoInfo;

//静态版本通讯录
//typedef struct Contact 
//{
//	PeoInfo data[MAX];//存放通讯录数据
//	int sz;//记录通讯录存了多少个数据
//}Contact;
//动态版本
typedef struct  Contact 
{
	PeoInfo* data;//存放数量
	int sz;//记录的当时通讯录中存放的人的信息个数
	int capacity;//记录的是通讯录的当前容量
}Contact;

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

//增加联系人
void AddContact(Contact* pc);

//显示全部联系人
void ShowContact(const Contact* pc);

//删除联系人
void DelContact(Contact* pc);

//查找联系人
void SearchContact(Contact* pc);

//修改联系人信息
void ModifyContact(Contact* pc);

//排序
void SortContact(Contact* pc);

//动态内存的释放
void DestoryContact(Contact* pc);

猜你喜欢

转载自blog.csdn.net/qq_72505850/article/details/133297889