C语言实现通讯录管理系统(超详细!-实现动态扩容,文件保存!)

目录

一、总体思路

二、各个部分函数实现

1、初始化  InitContact(Contact* p)

2、增加联系人 AddContact(Contact* p)

3、删除联系人 DelContact(Contact* p)

4、查找联系人信息 SearchContact(Contact* p)

5、修改联系人信息 ModifyContact(Contact* p)

6、排序联系人->按姓名?按年龄? SortContact(Contact* p)

7、 退出前保存文件 SaveContact(Contact* p) 

8、 退出销毁(释放内存)DestroyContact(Contact* p)

三、总体代码

1、rel.h

2、rel.c

3、text.c


一、总体思路

        需要什么功能?->1、添加联系人(同时将之前存储号的通讯录文件加载进来) 2、删除联系人 3、查找联系人 4、修改联系人 5、显示所有联系人 6、排序联系人->按什么排序?->年龄?名字? 7、以文件形式保存  8、退出系统(释放空间)

        需要存储什么信息?->1、姓名 2、年龄 3、性别 4、电话号码 5、地址

        要实现的是静态的?(不可扩容)还是动态的?(自动扩容)->动态!

确定基本框架如下:

enum option//功能确定,用于后续Switch
{
	Exit,
	Add,
	Del,
	Search,
	Modify,
	Show,
	Sort
};

typedef struct tp//存储信息
{
	char name[10];
	int age;
	char sex[SEX];
	char telp[TELP];
	char addr[ADDR];
}tp;


typedef struct Contact//动态储存,方便扩容
{
	tp* data;
	int sz;
	int capacity;
}Contact;

        写出函数接口以确定整体的作用->确定以结构体指针的形式传参数

如下:

void InitContact(Contact* p);//初始化

void AddContact(Contact* p);//添加

void ShowContact(Contact* p);//显示

void DelContact(Contact* p);//删除

void SearchContact(Contact* p);//查找

void ModifyContact(Contact* p);//修改

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

void DestroyContact(Contact* p);//退出销毁

void SaveContact(Contact* p);//保存文件

        接下来就是写下总体结构以及系统界面->确定以Switch函数来构造

如下:


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  *********         ******\n");
	printf("**************************************\n");

	printf("请选择>");
}

void text()
{
	int input = 0;
	Contact p;
	InitContact(&p);
	do
	{
		menu();
		scanf("%d", &input);
		system("cls");
		switch (input)
		{
		case Add:
			AddContact(&p);
			break;
		case Del:
			DelContact(&p);
			break;
		case Search:
			SearchContact(&p);
			break;
		case Modify:
			ModifyContact(&p);
			break;
		case Show:
			ShowContact(&p);
			break;
		case Sort:
			SortContact(&p);
			//namesort1(&p);
			break;
		case Exit:
			SaveContact(&p);
			DestroyContact(&p);
			printf("退出成功!\n");
			break;
		default:
			printf("输入错误,请重新输入!\n");
			break;
		}
	} while (input);
}


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

二、各个部分函数实现

1、初始化  InitContact(Contact* p)

void InitContact(Contact* p)
{
	assert(p);
	p->data = (tp*)malloc(sizeof(tp) * TELnum);//calloc
	if (p->data == NULL)
	{
		perror("malloc");
		return;
	}
	memset(p->data, 0, sizeof(p->data));
	p->sz = 0;
	p->capacity = TELnum;
	//文件中保存的信息加载到通讯录中
	LoadContact(p);
}

2、增加联系人 AddContact(Contact* p)


int CheckCapacity(Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		tp* ptr = (tp*)realloc(pc->data, (pc->capacity + INC)*sizeof(tp));
		if (ptr == NULL)
		{
			perror("CheckCapacity");
			return 0;
		}
		else
		{
			pc->data = ptr;
			pc->capacity += INC;
			printf("增容成功\n");
			return 1;
		}
	}
	return 1;
}

void AddContact(Contact* p)
{
	assert(p);
	if (0==CheckCapacity(&p))
	{
		printf("通讯录已满!\n");
		//EnContact(&p);
	}

	printf("\n请输入姓名>");
	scanf("%s",p->data[p->sz].name);
	printf("\n请输入年龄>");
	scanf("%d", &p->data[p->sz].age);
	printf("\n请输入性别>");
	scanf("%s", p->data[p->sz].sex);
	printf("\n请输入电话号码>");
	scanf("%s", p->data[p->sz].telp);
	printf("\n请输入地址>");
	scanf("%s", p->data[p->sz].addr);
	
	printf("在通讯录中成功添加%s的信息!\n", p->data[p->sz].name);
	p->sz++;
}

3、删除联系人 DelContact(Contact* p)

void DelContact(Contact* p)
{
	assert(p);
	int flag = 0, de = 0;
	if (p->sz == 0)
	{
		printf("通讯录为空!无法删除!\n");
		return;
	}
	printf("输入删除信息的姓名>");
	char arr[20]="0";
	scanf("%s",&arr);
	for (int i = 0; i < p->sz; i++)
	{
		if (strcmp(p->data[i].name, arr) == 0)//按照名字删除
		{
			flag = 1;
			de = i;
			break;
		}
	}
	if (flag == 1)
	{
		for (int j = de; j < p->sz - 1; j++)
		{
			p->data[j] = p->data[j + 1];
		}
		p->sz--;

		printf("成功删除!\n");
	}
	
	if (flag == 0)
		printf("通讯录中未找到该联系人!\n");
}

4、查找联系人信息 SearchContact(Contact* p)


void SearchContact(Contact* p)
{
	assert(p);
	if (p->sz == 0)
	{
		printf("通讯录为空,无法查找!\n");
			return;
	}
	printf("输入查找人的姓名>");
	char arr[20]="0";
	scanf("%s", arr);
	for (int i = 0; i < p->sz; i++)
	{

		if (strcmp(p->data[i].name, arr) == 0)//通过姓名查找
		{
			printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
			printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n",
				p->data[i].name,
				p->data[i].age,
				p->data[i].sex,
				p->data[i].telp,
				p->data[i].addr);
			
			return;
		}
	}
	printf("未找到该联系人!\n");

}

5、修改联系人信息 ModifyContact(Contact* p)


void ModifyContact(Contact* p)
{
	assert(p);
	if (p->sz == 0)
	{
		printf("通讯录为空,无法查找!\n");
		return;
	}
	printf("输入要修改人的姓名>");
	char arr[20]="0";
	scanf("%s", &arr);
	for (int i = 0; i < p->sz; i++)
	{
		if (strcmp(p->data[i].name, arr) == 0)//通过姓名修改
		{
			printf("\n请输入姓名>");
			scanf("%s", p->data[i].name);
			printf("\n请输入年龄>");
			scanf("%d", &p->data[i].age);
			printf("\n请输入性别>");
			scanf("%s", p->data[i].sex);
			printf("\n请输入电话号码>");
			scanf("%s", p->data[i].telp);
			printf("\n请输入地址>");
			scanf("%s", p->data[i].addr);

			printf("在通讯录中成功修改%s的信息!\n", p->data[i].name);
			return;
		}
	}
	printf("未找到要修改人%s的信息!", arr);
}

6、排序联系人->按姓名?按年龄? SortContact(Contact* p)

void SortContact(Contact* p)//懒得分装了0.0
{
	assert(p);
	if (p->sz == 0)
	{
		printf("\n通讯录为空,无法排序!!!\n");
		return;
	}
	printf("请选择排序的形式>");
	printf("\n*******************************");//提升菜单
	printf("\n**1、按名字排序  2、按年龄排序**");
	printf("\n*******************************\n");
	int ret = 0;
	scanf("%d", &ret);
	if(ret==1)
	{
		printf("选择升序或降序>");
		printf("\n**1、升**2、降**\n");
		int re = 0;
		Contact* pc = p;
		scanf("%d", &re);
		if (re == 1)//名字升序
		{
			
			int i = 0;
			int j = 0;
			tp tmp;
			for (i = 0; i < p->sz - 1; i++)
			{
				int flag = 1;
				for (j = 0; j < p->sz - i - 1; j++)
				{
					if (strcmp(p->data[j].name, p->data[j + 1].name) > 0)
					{
						tmp = p->data[j];
						p->data[j] = p->data[j + 1];
						p->data[j + 1] = tmp;
						flag = 0;
					}
				}
				if (flag == 1)
				{
					return;
				}
			}
			printf("\n排序成功\n");
			//namesort1(&pc);
		}
		else if (re == 2)//名字降序
		{
			
			int i = 0;
			int j = 0;
			tp tmp;
			for (i = 0; i < p->sz - 1; i++)
			{
				int flag = 1;
				for (j = 0; j < p->sz - i - 1; j++)
				{
					if (strcmp(p->data[j].name, p->data[j + 1].name) < 0)
					{
						tmp = p->data[j];
						p->data[j] = p->data[j + 1];
						p->data[j + 1] = tmp;
						flag = 0;
					}
				}
				if (flag == 1)
				{
					return;
				}
			}
			printf("\n排序成功\n");
			//namesort2(&pc);
		}
		else
		{
			printf("\n输入错误!\n");
		}

		//sort2(&p);
	}
	else if (ret == 2)
	{
		printf("选择升序或降序>");
		printf("\n**1、升**2、降**\n");
		int re = 0;
		scanf("%d", &re);
		switch (re)
		{
		case 1://年龄升序
			
			for (int i = 0; i < p->sz - 1; i++)
			{
				for (int j = 0; j < p->sz - 1 - i; j++)
				{
					if (p->data[j].age > p->data[j + 1].age)
					{
						tp temp = p->data[j];
						p->data[j] = p->data[j + 1];
						p->data[j + 1] = temp;
					}
				}
			}
			printf("\n排序成功!\n");
			break;
		case 2://年龄降序
			
			for (int i = 0; i < p->sz - 1; i++)
			{
				for (int j = 0; j < p->sz - 1 - i; j++)
				{
					if (p->data[j].age < p->data[j + 1].age)
					{
						tp temp = p->data[j];
						p->data[j] = p->data[j + 1];
						p->data[j + 1] = temp;
					}
				}
			}
			printf("\n排序成功!\n");
			break;
		default:
			printf("\n输入错误!\n");
			break;
		}
	}
	else
	{
		printf("\n输入错误!\n");
	}
}

7、 退出前保存文件 SaveContact(Contact* p) 

void LoadContact(Contact* pc)//这里为上面第一小电中的加载函数
{
	//打开文件
	FILE* pf = fopen("contact.dat", "rb");
	if (pf == NULL)
	{
		perror("LoadContact");
		return;
	}
	//读文件
	tp tmp = { 0 };
	while (fread(&tmp, sizeof(tp), 1, pf))
	{
		if (0 == CheckCapacity(pc))
			return;
		pc->data[pc->sz] = tmp;
		pc->sz++;
	}

	//关闭文件
	fclose(pf);
	pf = NULL;
}

void SaveContact(Contact* pc)
{
	FILE* pf = fopen("contact.dat", "wb");
	if (pf == NULL)
	{
		perror("SaveContact");
		return;
	}
	//写数据
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		fwrite(pc->data + i, sizeof(tp), 1, pf);
	}

	//关闭文件
	fclose(pf);
	pf = NULL;
}

8、 退出销毁(释放内存)DestroyContact(Contact* p)

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

三、总体代码

1、rel.h

#pragma once

#define NAME 20
#define SEX 5
#define TELP 12
#define ADDR 30
#define TELnum 20
#define INC 20

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



enum option
{
	Exit,
	Add,
	Del,
	Search,
	Modify,
	Show,
	Sort
};

typedef struct tp
{
	char name[10];
	int age;
	char sex[SEX];
	char telp[TELP];
	char addr[ADDR];
}tp;


typedef struct Contact
{
	tp* data;
	int sz;
	int capacity;
}Contact;



void InitContact(Contact* p);//初始化

void AddContact(Contact* p);//添加

void ShowContact(Contact* p);//显示

void DelContact(Contact* p);//删除

void SearchContact(Contact* p);//查找

void ModifyContact(Contact* p);//修改

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

void DestroyContact(Contact* p);//退出销毁

void SaveContact(Contact* p);//保存文件

2、rel.c

#define _CRT_SECURE_NO_WARNINGS 01

#include"rel.h"

int CheckCapacity(Contact* pc);

void LoadContact(Contact* pc)
{
	//打开文件
	FILE* pf = fopen("contact.dat", "rb");
	if (pf == NULL)
	{
		perror("LoadContact");
		return;
	}
	//读文件
	tp tmp = { 0 };
	while (fread(&tmp, sizeof(tp), 1, pf))
	{
		if (0 == CheckCapacity(pc))
			return;
		pc->data[pc->sz] = tmp;
		pc->sz++;
	}

	//关闭文件
	fclose(pf);
	pf = NULL;
}
void InitContact(Contact* p)
{
	assert(p);
	p->data = (tp*)malloc(sizeof(tp) * TELnum);//calloc
	if (p->data == NULL)
	{
		perror("malloc");
		return;
	}
	memset(p->data, 0, sizeof(p->data));
	p->sz = 0;
	p->capacity = TELnum;
	//文件中保存的信息加载到通讯录中
	LoadContact(p);
}


int CheckCapacity(Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		tp* ptr = (tp*)realloc(pc->data, (pc->capacity + INC)*sizeof(tp));
		if (ptr == NULL)
		{
			perror("CheckCapacity");
			return 0;
		}
		else
		{
			pc->data = ptr;
			pc->capacity += INC;
			printf("增容成功\n");
			return 1;
		}
	}
	return 1;
}

void AddContact(Contact* p)
{
	assert(p);
	if (0==CheckCapacity(&p))
	{
		printf("通讯录已满!\n");
		//EnContact(&p);
	}

	printf("\n请输入姓名>");
	scanf("%s",p->data[p->sz].name);
	printf("\n请输入年龄>");
	scanf("%d", &p->data[p->sz].age);
	printf("\n请输入性别>");
	scanf("%s", p->data[p->sz].sex);
	printf("\n请输入电话号码>");
	scanf("%s", p->data[p->sz].telp);
	printf("\n请输入地址>");
	scanf("%s", p->data[p->sz].addr);
	
	printf("在通讯录中成功添加%s的信息!\n", p->data[p->sz].name);
	p->sz++;
}

void ShowContact(Contact* p)
{
	assert(p);
	int i = 0;
	if (p->sz == 0)
	{
		printf("通讯录为空!\n");
		return;
	}
	printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
	while (i < p->sz)
	{
		printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n",
			p->data[i].name,
			p->data[i].age,
			p->data[i].sex,
			p->data[i].telp,
			p->data[i].addr);
		i++;
	}
}

void DelContact(Contact* p)
{
	assert(p);
	int flag = 0, de = 0;
	if (p->sz == 0)
	{
		printf("通讯录为空!无法删除!\n");
		return;
	}
	printf("输入删除信息的姓名>");
	char arr[20]="0";
	scanf("%s",&arr);
	for (int i = 0; i < p->sz; i++)
	{
		if (strcmp(p->data[i].name, arr) == 0)//按照名字删除
		{
			flag = 1;
			de = i;
			break;
		}
	}
	if (flag == 1)
	{
		for (int j = de; j < p->sz - 1; j++)
		{
			p->data[j] = p->data[j + 1];
		}
		p->sz--;

		printf("成功删除!\n");
	}
	
	if (flag == 0)
		printf("通讯录中未找到该联系人!\n");
}

void SearchContact(Contact* p)
{
	assert(p);
	if (p->sz == 0)
	{
		printf("通讯录为空,无法查找!\n");
			return;
	}
	printf("输入查找人的姓名>");
	char arr[20]="0";
	scanf("%s", arr);
	for (int i = 0; i < p->sz; i++)
	{

		if (strcmp(p->data[i].name, arr) == 0)//通过姓名查找
		{
			printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
			printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n",
				p->data[i].name,
				p->data[i].age,
				p->data[i].sex,
				p->data[i].telp,
				p->data[i].addr);
			
			return;
		}
	}
	printf("未找到该联系人!\n");

}

void ModifyContact(Contact* p)
{
	assert(p);
	if (p->sz == 0)
	{
		printf("通讯录为空,无法查找!\n");
		return;
	}
	printf("输入要修改人的姓名>");
	char arr[20]="0";
	scanf("%s", &arr);
	for (int i = 0; i < p->sz; i++)
	{
		if (strcmp(p->data[i].name, arr) == 0)//通过姓名修改
		{
			printf("\n请输入姓名>");
			scanf("%s", p->data[i].name);
			printf("\n请输入年龄>");
			scanf("%d", &p->data[i].age);
			printf("\n请输入性别>");
			scanf("%s", p->data[i].sex);
			printf("\n请输入电话号码>");
			scanf("%s", p->data[i].telp);
			printf("\n请输入地址>");
			scanf("%s", p->data[i].addr);

			printf("在通讯录中成功修改%s的信息!\n", p->data[i].name);
			return;
		}
	}
	printf("未找到要修改人%s的信息!", arr);
}


void SortContact(Contact* p)
{
	assert(p);
	if (p->sz == 0)
	{
		printf("\n通讯录为空,无法排序!!!\n");
		return;
	}
	printf("请选择排序的形式>");
	printf("\n*******************************");//提升菜单
	printf("\n**1、按名字排序  2、按年龄排序**");
	printf("\n*******************************\n");
	int ret = 0;
	scanf("%d", &ret);
	if(ret==1)
	{
		printf("选择升序或降序>");
		printf("\n**1、升**2、降**\n");
		int re = 0;
		Contact* pc = p;
		scanf("%d", &re);
		if (re == 1)//名字升序
		{
			
			int i = 0;
			int j = 0;
			tp tmp;
			for (i = 0; i < p->sz - 1; i++)
			{
				int flag = 1;
				for (j = 0; j < p->sz - i - 1; j++)
				{
					if (strcmp(p->data[j].name, p->data[j + 1].name) > 0)
					{
						tmp = p->data[j];
						p->data[j] = p->data[j + 1];
						p->data[j + 1] = tmp;
						flag = 0;
					}
				}
				if (flag == 1)
				{
					return;
				}
			}
			printf("\n排序成功\n");
			//namesort1(&pc);
		}
		else if (re == 2)//名字降序
		{
			
			int i = 0;
			int j = 0;
			tp tmp;
			for (i = 0; i < p->sz - 1; i++)
			{
				int flag = 1;
				for (j = 0; j < p->sz - i - 1; j++)
				{
					if (strcmp(p->data[j].name, p->data[j + 1].name) < 0)
					{
						tmp = p->data[j];
						p->data[j] = p->data[j + 1];
						p->data[j + 1] = tmp;
						flag = 0;
					}
				}
				if (flag == 1)
				{
					return;
				}
			}
			printf("\n排序成功\n");
			//namesort2(&pc);
		}
		else
		{
			printf("\n输入错误!\n");
		}

		//sort2(&p);
	}
	else if (ret == 2)
	{
		printf("选择升序或降序>");
		printf("\n**1、升**2、降**\n");
		int re = 0;
		scanf("%d", &re);
		switch (re)
		{
		case 1://年龄升序
			
			for (int i = 0; i < p->sz - 1; i++)
			{
				for (int j = 0; j < p->sz - 1 - i; j++)
				{
					if (p->data[j].age > p->data[j + 1].age)
					{
						tp temp = p->data[j];
						p->data[j] = p->data[j + 1];
						p->data[j + 1] = temp;
					}
				}
			}
			printf("\n排序成功!\n");
			break;
		case 2://年龄降序
			
			for (int i = 0; i < p->sz - 1; i++)
			{
				for (int j = 0; j < p->sz - 1 - i; j++)
				{
					if (p->data[j].age < p->data[j + 1].age)
					{
						tp temp = p->data[j];
						p->data[j] = p->data[j + 1];
						p->data[j + 1] = temp;
					}
				}
			}
			printf("\n排序成功!\n");
			break;
		default:
			printf("\n输入错误!\n");
			break;
		}
	}
	else
	{
		printf("\n输入错误!\n");
	}
}


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

void SaveContact(Contact* pc)
{
	FILE* pf = fopen("contact.dat", "wb");
	if (pf == NULL)
	{
		perror("SaveContact");
		return;
	}
	//写数据
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		fwrite(pc->data + i, sizeof(tp), 1, pf);
	}

	//关闭文件
	fclose(pf);
	pf = NULL;
}

3、text.c

#define _CRT_SECURE_NO_WARNINGS 01
#include"rel.h"

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  *********         ******\n");
	printf("**************************************\n");

	printf("请选择>");
}

void text()
{
	int input = 0;
	Contact p;
	InitContact(&p);
	do
	{
		menu();
		scanf("%d", &input);
		system("cls");
		switch (input)
		{
		case Add:
			AddContact(&p);
			break;
		case Del:
			DelContact(&p);
			break;
		case Search:
			SearchContact(&p);
			break;
		case Modify:
			ModifyContact(&p);
			break;
		case Show:
			ShowContact(&p);
			break;
		case Sort:
			SortContact(&p);
			//namesort1(&p);
			break;
		case Exit:
			SaveContact(&p);
			DestroyContact(&p);
			printf("退出成功!\n");
			break;
		default:
			printf("输入错误,请重新输入!\n");
			break;
		}
	} while (input);
}


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

猜你喜欢

转载自blog.csdn.net/weixin_64038246/article/details/131737432