C语言实现通讯录管理系统

x33g5p2x  于2022-02-07 转载在 其他  
字(11.9k)|赞(0)|评价(0)|浏览(323)
  1. 需求分析

  2. 程序架构

  3. 代码实现(分函数呈现)

(1)主函数代码实现

(2)菜单函数的实现

(3)初始化功能实现

(4)添加联系人功能实现

(5)删除通讯录中的信息

(6)查找通讯录中联系人的信息

(7)查找函数实现

(8)修改联系人的信息

(9)打印通讯录中联系人的信息

(10)对通讯录中联系人的信息进行排序

(11)清空通讯录中联系人的信息

  1. 代码呈现(分文件实现)

(1)test.c

(2)contact.h

(3)contact.c

1. 需求分析

通过C语言实现简单的通讯录管理系统,要求实现的功能有:增加联系人信息、删除联系人信息、查找联系人信息、修改联系人信息、清空联系人信息、对联系人的信息进行排序、显示联系人信息

2. 程序架构

程序分为test.c、contact.c两个源文件和contact.h一个头文件。

test.c:主函数接口引入。

contact.c:函数主要实现

contact.h:头文件引入、函数声明、结构体声明。

3. 代码实现(分函数呈现)

(1)主函数代码实现

int main()
{
	//创建通讯录
	struct contact con;//con就是通讯录,里面包含1000个元素的数组和size
	//初始化通讯录
	Init_Contact(&con);
	int input = 0;
	int size = 0;//记录当前有多少人
	do
	{
		menu();
		printf("请选择->");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			//增加
			Add_Contacter(&con);
			break;
		case DEL:
			//删除
			Del_Contacter(&con);
			break;
		case SEARCH:
			//查找
			Find_Contacter(&con);
			break;
		case MODIFY:
			//修改
			Mod_Contacter(&con);
			break;
		case SHOW:
			//打印
			Print_Contacter(&con);
			break;
		case CLEAR:
			//清空
			Clear_Contacter(&con);
			break;
		case SORT:
			//排序
			Sort_Contacter(&con);
			break;
		case EXIT:
		    //退出
			printf("退出通讯录!\n");
			break;
		default:
			printf("选择错误,请重新输入!\n");
		}
	} while (input);
	return 0;
}

分析:主要是引入函数的接口,此处用了常见的do while循环,并且将input变量作为while()后面括号中的条件,此处是一个极其巧妙的运用,当input变量为0时循环结束,程序终止,此时也与前面的switch和case进行了一一对应。

(2)菜单函数的实现

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

分析:简单运用printf将菜单进行输出,通过*来使输出形式更加清晰简洁美观。

(3)初始化功能实现

//初始化通讯录中的信息
void Init_Contact(struct contact* ps)
{
	memset(ps->data, 0, sizeof(ps->data));
	ps->size = 0;//设置通讯录最初只有0个元素
}

分析:通过memset()内存函数初始化通讯录中的信息,同时将size记录联系人数目的变量设置为0。

(4)添加联系人功能实现

//添加通讯录中的信息
void Add_Contacter(struct contact* ps)
{
	if (ps->size == MAX_NUM)
	{
		printf("通讯录已满!无法继续增加!\n");
	}
	else
	{
		printf("请输入名字:");
		scanf("%s", &ps->data[ps->size].name);
		printf("请输入年龄:");
		scanf("%d", &ps->data[ps->size].age);
		printf("请输入性别:");
		scanf("%s", &ps->data[ps->size].sex);
		printf("请输入电话:");
		scanf("%s", &ps->data[ps->size].phone);
		printf("请输入地址:");
		scanf("%s", &ps->data[ps->size].address);

		ps->size++;
		printf("添加成功!\n");
	}
}

分析:在进行添加时要注意进行分情况讨论,首先就是当联系人数目满了的时候就无法继续添加,只有当联系人数目未满的时候才能继续添加,添加后,要将记录联系人数目的变量size进行加一。

(5)删除通讯录中的信息

//删除通讯录中的信息
void Del_Contacter(struct contact* ps)
{
	char name[MAX_NAME];
	printf("请输入你要删除的联系人的姓名:");
	scanf("%s", name);
	//查找要删除的人所在的位置
	//找到了返回名字所在元素的下标,没找到就返回-1
	int pos = Find_byName(ps,name);
	if (pos==-1)//删除的人不存在
	{
		printf("要删除的人不存在!\n");
	}
	else//删除
	{
		int j = 0;
		for (j = pos; j < ps->size-1; j++)
		{
			ps->data[j] = ps->data[j + 1];
		}
		ps->size--;
		printf("删除成功!\n");
	}
}

分析:删除操作并不复杂,就是先查找到我们想要删除的那个联系人,然后将这个联系人后面的信息逐个向前进行覆盖,同时将记录联系人数目的变量size的值进行减1。

(6)查找通讯录中联系人的信息

//查找通讯录中的信息
void Find_Contacter(const struct contact* ps)
{
	char name[MAX_NAME];
	printf("请输入你要查找的联系人的姓名:");
	scanf("%s", name);
	int pos = Find_byName(ps, name);
	if (pos==-1)//查找的人不存在
	{
		printf("要查找的人不存在!\n");
	}
	else
	{
		printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n", "姓名", "年龄", "性别", "电话", "地址");
		printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n", ps->data[pos].name,
			ps->data[pos].age,
			ps->data[pos].sex,
			ps->data[pos].phone,
			ps->data[pos].address);
	}
}

分析:首先先通过查找函数将我们想要查找到的联系人找到,然后通过printf函数打印联系人的信息。

(7)查找函数实现

static int Find_byName(const struct contact* ps, char name[MAX_NAME])
{
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		if (0 == strcmp(ps->data[i].name, name))
		{
			return i;
		}
	}
	return -1;
}

分析:此处查找函数是通过遍历联系人中的信息进行实现的,当我们想查找的联系人的信息与某个联系人的信息一致时就停止下来,如果能够找到就返回其对应的下标,如果找不到就返回-1。

(8)修改联系人的信息

//修改通讯录中的信息
void Mod_Contacter(struct contact* ps)
{
	char name[MAX_NAME];
	printf("请输入你要修改的联系人的姓名:");
	scanf("%s", name);
	int pos = Find_byName(ps, name);
	if (pos==-1)//修改的人不存在
	{
		printf("要修改的人不存在!\n");
	}
	else
	{
		printf("请输入名字:");
		scanf("%s", &ps->data[pos].name);
		printf("请输入年龄:");
		scanf("%d", &ps->data[pos].age);
		printf("请输入性别:");
		scanf("%s", &ps->data[pos].sex);
		printf("请输入电话:");
		scanf("%s", &ps->data[pos].phone);
		printf("请输入地址:");
		scanf("%s", &ps->data[pos].address);
		printf("修改成功!\n");
	}
}

分析:修改联系人的信息与上面其实类似,首先是找到我们想要修改的联系人的信息,然后再进行修改。

(9)打印通讯录中联系人的信息

//打印通讯录中的信息
void Print_Contacter(const struct contact* ps)
{
	if (ps->size == 0)
	{
		printf("通讯录为空!\n");
	}
	else
	{
		//标题
		printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n",  "姓名", "年龄", "性别", "电话", "地址");
		int i = 0;
		while (i < ps->size)
		{
			//数据
			printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n", ps->data[i].name, 
				ps->data[i].age, 
				ps->data[i].sex, 
				ps->data[i].phone, 
				ps->data[i].address);
			i++;
		}
	}
}

分析:这个功能并不难实现,就是设置一个循环变量i,然后从头开始对通讯录信息进行遍历,当i小于size的时候将对应联系人的信息打印出来。

(10)对通讯录中联系人的信息进行排序

//对通讯录中的信息进行排序
//排序函数
//1.按照姓名进行排序
int Conpare_ByName(const void *e1,const void *e2)
{
	return strcmp(((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name);
}
//2.按照年龄进行排序
int Conpare_ByAge(const void* e1, const void* e2)
{
	return ((struct PeoInfo*)e1)->age-((struct PeoInfo*)e2)->age;
}
//3.按照住址进行排序
int Conpare_ByAddress(const void* e1, const void* e2)
{
	return strcmp(((struct PeoInfo*)e1)->address, ((struct PeoInfo*)e2)->address);
}
void Sort_Contacter(struct contact* ps)
{
	printf("请选择你想排序的方式:\n");
	printf("1.姓名\n2.年龄\n3.住址\n");
	int input = 0;
	scanf("%d", &input);
	switch (input)
	{
	case 1:
		qsort(ps->data,ps->size,sizeof(ps->data[0]),Conpare_ByName);
		printf("排序成功\n");
		break;
	case 2:
		qsort(ps->data, ps->size, sizeof(ps->data[0]), Conpare_ByAge);
		printf("排序成功\n");
		break;
	case 3:
		qsort(ps->data, ps->size, sizeof(ps->data[0]), Conpare_ByAddress);
		printf("排序成功\n");
		break;
	}
}

分析:此处运用了qsort快速排序的函数,此处的关键就是设定好自己想要排序的依据,比如我们想根据年龄或者名字进行排序,此处要求掌握快速排序函数的使用。

(11)清空通讯录中联系人的信息

//清空通讯中的信息
void Clear_Contacter(struct contact* ps)
{
	memset(ps->data, 0, sizeof(ps->data));
	ps->size = 0;
	printf("清空成功!\n");
}

分析:此处其实类似于初始化联系人的信息,就是将那段内存空间中的数据使用memset函数全部设置为0,然后将记录联系人数目的变量size设定为0。

4. 代码呈现(分文件实现)

(1)test.c

#include"contact.h"
enum Option
{
	EXIT,//0
	ADD,//1
	DEL,//2
	SEARCH,//3
	MODIFY,//4
	SHOW,//5
	CLEAR,//6
	SORT//7
};
void menu()
{
	printf("************************************\n");
	printf("****  1.add         2.del       ****\n");
	printf("****  3.search      4.modify    ****\n");
	printf("****  5.show        6.clear     ****\n");
	printf("****  7.sort        0.exit      ****\n");
	printf("************************************\n");
}
//测试函数的功能
int main()
{
	//创建通讯录
	struct contact con;//con就是通讯录,里面包含1000个元素的数组和size
	//初始化通讯录
	Init_Contact(&con);
	int input = 0;
	int size = 0;//记录当前有多少人
	do
	{
		menu();
		printf("请选择->");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			//增加
			Add_Contacter(&con);
			break;
		case DEL:
			//删除
			Del_Contacter(&con);
			break;
		case SEARCH:
			//查找
			Find_Contacter(&con);
			break;
		case MODIFY:
			//修改
			Mod_Contacter(&con);
			break;
		case SHOW:
			//打印
			Print_Contacter(&con);
			break;
		case CLEAR:
			//清空
			Clear_Contacter(&con);
			break;
		case SORT:
			//排序
			Sort_Contacter(&con);
			break;
		case EXIT:
		    //退出
			printf("退出通讯录!\n");
			break;
		default:
			printf("选择错误,请重新输入!\n");
		}
	} while (input);
	return 0;
}

(2)contact.h

#pragma once
#define MAX_NUM 100
#define MAX_NAME 20
#define MAX_PHONE 12
#define MAX_SEX 5
#define MAX_ADDRESS 30
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct PeoInfo
{
	char name[MAX_NAME];
	char phone[MAX_PHONE];
	char sex[MAX_SEX];
	char address[MAX_ADDRESS];
	int age;
};
struct contact
{
	struct PeoInfo data[MAX_NUM];
	int size;//记录当前已经有的元素个数
};
//声明函数
//初始化通讯录的函数
void Init_Contact(struct contact* ps);
//增加一个信息到通讯录
void Add_Contacter(struct contact* ps);
//删除指定的联系人
void Del_Contacter(struct contact* ps);
//查找指定人的信息
void Find_Contacter(const struct contact* ps);
//修改指定人的信息
void Mod_Contacter(struct contact* ps);
//打印通讯录中的信息
void Print_Contacter(const struct contact* ps);
//对通讯录中的联系人进行排序
void Sort_Contacter(struct contact* ps);
//清空通讯录中的信息
void Clear_Contacter(struct contact* ps);

(3)contact.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
//实现函数的功能
static int Find_byName(const struct contact* ps, char name[MAX_NAME])
{
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		if (0 == strcmp(ps->data[i].name, name))
		{
			return i;
		}
	}
	return -1;
}
//初始化通讯录中的信息
void Init_Contact(struct contact* ps)
{
	memset(ps->data, 0, sizeof(ps->data));
	ps->size = 0;//设置通讯录最初只有0个元素
}
//添加通讯录中的信息
void Add_Contacter(struct contact* ps)
{
	if (ps->size == MAX_NUM)
	{
		printf("通讯录已满!无法继续增加!\n");
	}
	else
	{
		printf("请输入名字:");
		scanf("%s", &ps->data[ps->size].name);
		printf("请输入年龄:");
		scanf("%d", &ps->data[ps->size].age);
		printf("请输入性别:");
		scanf("%s", &ps->data[ps->size].sex);
		printf("请输入电话:");
		scanf("%s", &ps->data[ps->size].phone);
		printf("请输入地址:");
		scanf("%s", &ps->data[ps->size].address);

		ps->size++;
		printf("添加成功!\n");
	}
}
//删除通讯录中的信息
void Del_Contacter(struct contact* ps)
{
	char name[MAX_NAME];
	printf("请输入你要删除的联系人的姓名:");
	scanf("%s", name);
	//查找要删除的人所在的位置
	//找到了返回名字所在元素的下标,没找到就返回-1
	int pos = Find_byName(ps,name);
	if (pos==-1)//删除的人不存在
	{
		printf("要删除的人不存在!\n");
	}
	else//删除
	{
		int j = 0;
		for (j = pos; j < ps->size-1; j++)
		{
			ps->data[j] = ps->data[j + 1];
		}
		ps->size--;
		printf("删除成功!\n");
	}
}
//查找通讯录中的信息
void Find_Contacter(const struct contact* ps)
{
	char name[MAX_NAME];
	printf("请输入你要查找的联系人的姓名:");
	scanf("%s", name);
	int pos = Find_byName(ps, name);
	if (pos==-1)//查找的人不存在
	{
		printf("要查找的人不存在!\n");
	}
	else
	{
		printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n", "姓名", "年龄", "性别", "电话", "地址");
		printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n", ps->data[pos].name,
			ps->data[pos].age,
			ps->data[pos].sex,
			ps->data[pos].phone,
			ps->data[pos].address);
	}
}
//修改通讯录中的信息
void Mod_Contacter(struct contact* ps)
{
	char name[MAX_NAME];
	printf("请输入你要修改的联系人的姓名:");
	scanf("%s", name);
	int pos = Find_byName(ps, name);
	if (pos==-1)//修改的人不存在
	{
		printf("要修改的人不存在!\n");
	}
	else
	{
		printf("请输入名字:");
		scanf("%s", &ps->data[pos].name);
		printf("请输入年龄:");
		scanf("%d", &ps->data[pos].age);
		printf("请输入性别:");
		scanf("%s", &ps->data[pos].sex);
		printf("请输入电话:");
		scanf("%s", &ps->data[pos].phone);
		printf("请输入地址:");
		scanf("%s", &ps->data[pos].address);
		printf("修改成功!\n");
	}
}
//打印通讯录中的信息
void Print_Contacter(const struct contact* ps)
{
	if (ps->size == 0)
	{
		printf("通讯录为空!\n");
	}
	else
	{
		//标题
		printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n",  "姓名", "年龄", "性别", "电话", "地址");
		int i = 0;
		while (i < ps->size)
		{
			//数据
			printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n", ps->data[i].name, 
				ps->data[i].age, 
				ps->data[i].sex, 
				ps->data[i].phone, 
				ps->data[i].address);
			i++;
		}
	}
}
//对通讯录中的信息进行排序
//排序函数
//1.按照姓名进行排序
int Conpare_ByName(const void *e1,const void *e2)
{
	return strcmp(((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name);
}
//2.按照年龄进行排序
int Conpare_ByAge(const void* e1, const void* e2)
{
	return ((struct PeoInfo*)e1)->age-((struct PeoInfo*)e2)->age;
}
//3.按照住址进行排序
int Conpare_ByAddress(const void* e1, const void* e2)
{
	return strcmp(((struct PeoInfo*)e1)->address, ((struct PeoInfo*)e2)->address);
}
void Sort_Contacter(struct contact* ps)
{
	printf("请选择你想排序的方式:\n");
	printf("1.姓名\n2.年龄\n3.住址\n");
	int input = 0;
	scanf("%d", &input);
	switch (input)
	{
	case 1:
		qsort(ps->data,ps->size,sizeof(ps->data[0]),Conpare_ByName);
		printf("排序成功\n");
		break;
	case 2:
		qsort(ps->data, ps->size, sizeof(ps->data[0]), Conpare_ByAge);
		printf("排序成功\n");
		break;
	case 3:
		qsort(ps->data, ps->size, sizeof(ps->data[0]), Conpare_ByAddress);
		printf("排序成功\n");
		break;
	}
}
//清空通讯中的信息
void Clear_Contacter(struct contact* ps)
{
	memset(ps->data, 0, sizeof(ps->data));
	ps->size = 0;
	printf("清空成功!\n");
}

相关文章