C语言文件版+动态版通讯录

C语言文件版+动态版通讯录,第1张

1.头文件Contact.h

#define DEFAULT_SZ 3
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 20
#include
#include
#include
#include
enum Option
{
	EXIT,
	ADD,
	DEL,
	SERACH,
	MODIFY,
	SHOW,
	SAVE
};
//个人信息
typedef struct PeoInfo
{
	char name[MAX_NAME];
	int age;
	char sex[MAX_SEX];
	char tele[MAX_TELE];
	char addr[MAX_ADDR];
}PeoInfo;
//通讯录
typedef struct Contact
{
	struct PeoInfo* data;//联系人
	int size;//当前存放的联系人的数量
	int capacity;//最大容量
}Contact;

//各种功能的实现
//初始化通讯录
void InitContact(Contact* ps);
//添加联系人
void AddContact(Contact* ps);
//显示联系人信息
void ShowContact(const Contact* ps);
//删除联系人
void DelContact(Contact* ps);
//查找联系人
void SearchContact(const Contact* ps);
//修改信息
void ModifyContact(Contact* ps);
void DestoryContact(Contact* ps);
//将通讯录中的联系人信息写入文件中
void SaveContact(Contact* ps);
//将文件中的联系人信息读入到通讯录中
void LoadContact(Contact* ps);

2.源文件Contact.c    各种功能实现

#include"Contact.h"
void check_Capacity(Contact* ps);
void LoadContact(Contact* ps)
{
	//将文件中的联系人信息读入通讯录中
	PeoInfo tmp;
	FILE* pfRead = fopen("Contact.dat", "rb");
	if (pfRead == NULL)
	{
		printf("Loadontact::%s\n", strerror(errno));
		return;
	}
	//读文件
	while (fread(&tmp, sizeof(PeoInfo), 1, pfRead))
	{
		check_Capacity(ps);
		ps->data[ps->size] = tmp;
		ps->size++;
	}
	fclose(pfRead);
	pfRead = NULL;
}
//初始化通讯录
void InitContact(Contact* ps)
{
	ps->data = (PeoInfo*)malloc(DEFAULT_SZ * sizeof(PeoInfo));
	if (ps->data == NULL)
	{
		return;
	}
	ps->size = 0;
	ps->capacity = DEFAULT_SZ;
	//将保存的数据读入到通讯录中
	LoadContact(ps);
}

void check_Capacity(Contact* ps)
{
	//使用realloc进行动态开辟空间的扩容
	if (ps->size == ps->capacity)
	{
		//满了开始扩容
		PeoInfo* ptr = realloc(ps->data, (ps->capacity + 2) * sizeof(PeoInfo));
		if (ptr != NULL)
		{
			ps->data = ptr;
			ps->capacity += 2;
			printf("增容成功\n");
		}
	}
}
//添加信息
void AddContact(Contact* ps)
{
	//1.先检查有没有满
	//满了,则什么也不做
	//不满就扩容,每次扩2
	check_Capacity(ps);
	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].tele);
	printf("请输入地址:");
	scanf("%s", ps->data[ps->size].addr);

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

}

//显示信息
void ShowContact(const struct Contact* ps)
{
	if (ps->size == 0)
	{
		printf("通讯录为空!\n");
	}
	else
	{
		int i = 0;//用来记录通讯录信息的个数
		//标题
		printf("%-20s\t %-4s\t %-5s\t %-12s\t %-20s\n", "姓名", "年龄", "性别", "电话", "地址");
		for (i = 0; i < ps->size; i++)
		{
			//数据
			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].tele,
				ps->data[i].addr);
		}
	}
}

//查找功能
static int FindByName(const struct Contact* ps, char name[MAX_NAME])
{
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		if (strcmp(ps->data[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}


//删除信息
void DelContact(struct Contact* ps)
{
	//1.查找姓名
	char name[MAX_NAME];
	printf("请输入想要删除的联系人的姓名:\n");
	scanf("%s", name);
	int pos = FindByName(ps, name);
	//2.删除
	if (pos == -1)
	{
		printf("该联系人不存在的!\n");
	}
	else
	{
		//删除数据
		int j = 0;
		for (j = pos; j < ps->size; j++)
		{
			ps->data[j] = ps->data[j + 1];
		}
		ps->size--;
		printf("删除成功!\n");
	}
}

//查找功能
void SearchContact(const struct Contact* ps)
{
	char name[MAX_NAME];
	printf("请输入要查找人的姓名:\n");
	int pos = FindByName(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].tele,
			ps->data[pos].addr);
	}
}

//修改信息
void ModifyContact(struct Contact* ps)
{
	char name[MAX_NAME];
	printf("请输入要修改联系人的姓名:\n");
	scanf("%s", name);
	int pos = FindByName(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].tele);
		printf("请输入地址:");
		scanf("%s", ps->data[pos].addr);

		printf("修改成功!\n");
	}
}

void DestoryContact(Contact* ps)
{
	free(ps->data);
	ps->data = NULL;
}

//保存联系人信息
void SaveContact(Contact* ps)
{
	//将通讯录中的联系人信息以二进制形式写入文件中
	FILE* pfWrite = fopen("Contact.dat", "wb");
	if (pfWrite == NULL)
	{
		printf("SaveContact::%s\n", strerror(errno));
		return;
	}
	//写文件
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		{
			fwrite(&ps->data[i], sizeof(PeoInfo), 1, pfWrite);
		}
	}
	printf("保存成功\n");
	fclose(pfWrite);
	pfWrite = NULL;
}

主要功能实现有:添加联系人 、删除联系人、查找联系人、修改联系人信息、显示联系人信息、保存联系人信息、初始化联系人信息

3.源文件text.c   功能测试

#include"contact.h"
void menu()
{
	printf("******************************\n");
	printf("*****         通讯录    ***** \n");
	printf("** 1.添加信息    2.删除信息 **\n");
	printf("** 3.查找信息    4.修改信息 **\n");
	printf("** 5.显示信息    6.保存数据 **\n");
	printf("***0.退出程序               **\n");
	printf("******************************\n");
}
int main()
{
	int input = 0;
	struct Contact con;//通讯仓,里面包含data和size以及capacity 
	InitContact(&con);//初始化通讯录
	do
	{
		menu();
		printf("请输入数字进行选择:\n");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			AddContact(&con);
			break;
		case DEL:
			DelContact(&con);
			break;
		case SERACH:
			SearchContact(&con);
			break;
		case MODIFY:
			ModifyContact(&con);
			break;
		case SHOW:
			ShowContact(&con);
			break;
		case SAVE:
			SaveContact(&con);
			break;
		case EXIT:
			//销毁通讯录   释放空间
			SaveContact(&con);
			DestoryContact(&con);
			printf("退出通讯录!\n");
			break;
		default:
			printf("输入错误,请重新输入!\n");
			break;
		}
	} while (input);
	return 0;
}

注:该小程序涉及的知识点:

1.枚举变量的使用

2.typedef  重定义类型名 

3.文件管理相关 *** 作。

主要是用于初始化时加载之前保存的通讯录的信息,以及保存通讯录信息到文件中。

补充一下文件管理的几个知识点:

a.打开文件函数:fopen:fopen("Contact.dat", "rb");

   关闭文件函数:fclose:fclose(pfWrite);   pfWrite = NULL;

第一个参数是文件名,第二个参数是相关 *** 作,主要有以下 *** 作:

     

 

b.   将数据写入文件中的fwrite函数的用法:  fwrite(&ps->data[i], sizeof(PeoInfo), 1, pfWrite);  

总共四个参数:第一个参数是要写内容的来源。第二个参数是要写数据的大小。第三个参数是要写数据的数量。第四个参数是要写入数据的文件目的地

c.将文件中的数据读入到通讯录中的函数fread的用法:fread(&tmp, sizeof(PeoInfo), 1, pfRead)

总共也是四个函数:第一个参数是读入数据的目的地。第二个参数的是要读数据的大小。第三个参数是要读入数据的数量。第四个参数是要读入数据的来源

4.补充一下使用枚举变量的优点:

1.增加代码的可读性和可扩展性

2.与宏定义的标识符相比较枚举有检查类型,更加严谨。

3.便于调试

4.使用方便,一次可以定义多个常量。

枚举变量的成员变量初始值默认为0。可以自己定义初始值,每次向后加一。

5.动态内存开辟函数malloce和realloc函数使用

补充:

1.malloc:void*malloc(int size);

 malloc向系统申请分配size字节的内存空间,返回类型为void*类型。该函数不会初始化内存空间中的字节

2.calloc:  void*calloc(int n,int size);

calloc第一个参数是要申请的数量,第二个参数是申请的字节数。该函数会初始化内存空间中的所有字节为0

3.realloc:void* realloc(void* ptr,int size);

realloc是用来调整动态开辟内存空间的大小

realloc第一个参数是要调整内存空间的地址,第二个是总共的字节数。

一定记得这三个函数与free(释放动态内存空间函数)搭配使用,否则可能造成内存泄漏

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/676073.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-19
下一篇 2022-04-19

发表评论

登录后才能评论

评论列表(0条)

保存