模拟实现通讯录的功能(文件版本)

在前面的文章中,我介绍了通讯录的静态版本和动态版本,现在我来介绍通讯录的文件版本,注意这里通讯录的文件版本是建立在动态版本通讯录的基础上的,所以还不知道动态版本的通讯录请前往前面文章观看学习。





在这里,我只列出与动态版本不同的地方,通讯录依然包括test.c和contact.c和contact.h的三个文档,另外在项目文件夹还要有个data.txt文档存放着通讯录的信息。

初始化函数

void InitBoard(struct contact* pc)
{
    assert(pc != NULL);
	pc->data = (struct people*)malloc(sizeof(struct people) * DEFAULT_INT);
	if(pc->data == NULL)
	{
	    perror("InitBoard()");
	}
	pc->capacity = DEFAULT_INT;
	pc->sz = 0;
	//读取文件夹的通讯录信息
	LoadContact(pc);
}


读取文件夹的联系人的信息的函数

static int Check_Capacity(struct contact* pc);    //检查通讯录是否满了的函数声明

void LoadContact(struct contact* pc)
{
	struct people tmp = {0};
	//打开文件
	FILE* pfR = fopen("data.txt","rb");
	assert(pc != NULL);
	if(pfR == NULL)
	{
	    perror("LoadContact::fopen");
	}
	//读文件
	while(fread(&tmp,sizeof(struct people),1,pfR))
	{
	    //检验内存是否满了
		Check_Capacity(pc);
		pc->data[pc->sz] = tmp;
		pc->sz++;
	}
	//关闭文件
	fclose(pfR);
	pfR = NULL;
}


保存通讯录信息到文件夹的函数

void SaveContact(struct contact* pc)
{
	int i = 0;
	//打开文件
	FILE* pfw = fopen("data.txt","wb");
    assert(pc != NULL);
	if(pfw == NULL)
	{
	    perror("SaveContact::fopen");
	}
	//写文件
	for(i=0;i<pc->sz;i++)
	{
	    fwrite(pc->data+i,sizeof(struct people),1,pfw);
	}
	//关闭文件
	fclose(pfw);
	pfw = NULL;
}


contact.c文档代码

#include"contact.h"

static int Check_Capacity(struct contact* pc);    //检查通讯录是否满了的函数声明

void LoadContact(struct contact* pc)
{
	struct people tmp = {0};
	//打开文件
	FILE* pfR = fopen("data.txt","rb");
	assert(pc != NULL);
	if(pfR == NULL)
	{
	    perror("LoadContact::fopen");
	}
	//读文件
	while(fread(&tmp,sizeof(struct people),1,pfR))
	{
	    //检验内存是否满了
		Check_Capacity(pc);
		pc->data[pc->sz] = tmp;
		pc->sz++;
	}
	//关闭文件
	fclose(pfR);
	pfR = NULL;
}

void InitBoard(struct contact* pc)
{
    assert(pc != NULL);
	pc->data = (struct people*)malloc(sizeof(struct people) * DEFAULT_INT);
	if(pc->data == NULL)
	{
	    perror("InitBoard()");
	}
	pc->capacity = DEFAULT_INT;
	pc->sz = 0;
	//读取文件夹的通讯录信息
	LoadContact(pc);
}
static int Check_Capacity(struct contact* pc)                         //检查通讯录是否满了。满了就增容
{
	assert(pc != NULL);
	if(pc->sz == pc->capacity)
	{
		pc->data = (struct people*)realloc(pc->data,sizeof(struct people) * (pc->capacity + INT_SZ));
		if(pc->data == NULL)
		{
		    perror("Check_Capacity()");
			return 0;
		}
		pc->capacity += INT_SZ;
		printf("增容成功\n");
		return 1;
	}
	else
	{
	    return 1;
	}
}
void DestroyContact(struct contact* pc)
{
    assert(pc != NULL);
	free(pc->data);
	pc->data = NULL;
	pc->capacity = 0;
	pc->sz = 0;
}
void Addcontact(struct contact* pc)
{
	assert(pc != NULL);
    if(0 == Check_Capacity(pc))
	{
	    return;
	}
	else
	{
	    printf("请输入想要添加联系人的名字:>");
		scanf("%s",pc->data[pc->sz].name);
		printf("请输入该联系人的性别:>");
		scanf("%s",pc->data[pc->sz].sex);
		printf("请输入该联系人的地址:>");
		scanf("%s",&pc->data[pc->sz].addr);
		printf("请输入该联系人的电话:>");
		scanf("%s",&pc->data[pc->sz].tele);
		printf("请输入该联系人的年龄:>");
		scanf("%d",&(pc->data[pc->sz].age));

		pc->sz++;
		printf("添加联系人成功\n");
	}
}

int Findpeople(struct contact* pc,char name[])
{
	int i = 0;
    assert(pc != NULL);
	for(i=0;i<pc->sz;i++)
	{
	    if(strcmp(pc->data[i].name,name) == 0)
		{
		    return i;
		}
	}
	return -1;
}
void Delcontact(struct contact* pc)
{

     char name[nameMax];
	 int ret = 0;
	 int i = 0;
	 assert(pc != NULL);
	 printf("请输入想要删除的联系人:>");
	 scanf("%s",name);
	 ret = Findpeople(pc,name);
	 if(ret == -1)
	 {
	     printf("找不到该联系人\n");
	 }
	 else
	 {
	     for(i=ret;i<pc->sz-1;i++)
		 {
		     pc->data[i] = pc->data[i+1];
		 }
		 pc->sz--;
		 printf("删除该联系人成功\n");
	 }
}
void SearchContact(struct contact* pc)
{
    char name[nameMax];
	int ret = 0;
	assert(pc != NULL);
	printf("请输入想要联系人的名字:>");
	scanf("%s",&name);
	ret = Findpeople(pc,name);
	if(ret == -1)
	{
	    printf("找不到该联系人\n");
	}
	else
	{
	    printf("%-20s\t%-4s\t%-30s\t%-12s\t%-5s\t\n","名字","性别","地址","电话","年龄");
		printf("%-20s\t%-4s\t%-30s\t%-12s\t%-5d\t\n",pc->data[ret].name,
			pc->data[ret].sex,
			pc->data[ret].addr,
			pc->data[ret].tele,
			pc->data[ret].age);
	}
}
void ModifyContact(struct contact* pc)
{
    char name[nameMax];
	int ret = 0;
	assert(pc != NULL);
	printf("请输入你要修改的联系人:>");
	scanf("%s",name);
	ret = Findpeople(pc,name);
	if(ret == -1)
	{
	    printf("找不到该联系人\n");
	}
	else
	{
	    printf("请重新输入该联系人的信息\n");
		printf("请输入该联系人的名字:>");
		scanf("%s",pc->data[ret].name);
		printf("请输入该联系人的性别:>");
		scanf("%s",pc->data[ret].sex);
		printf("请输入该联系人的地址:>");
		scanf("%s",&pc->data[ret].addr);
		printf("请输入该联系人的电话:>");
		scanf("%s",&pc->data[ret].tele);
		printf("请输入该联系人的年龄:>");
		scanf("%d",&(pc->data[ret].age));
	}
}
void ShowContact(struct contact* pc)
{
    int i = 0;
    printf("%-20s\t%-4s\t%-30s\t%-12s\t%-5s\t\n","名字","性别","地址","电话","年龄");
	for(i=0;i<pc->sz;i++)
	{
		printf("%-20s\t%-4s\t%-30s\t%-12s\t%-5d\t\n",pc->data[i].name,
			pc->data[i].sex,
			pc->data[i].addr,
			pc->data[i].tele,
			pc->data[i].age);
	}
}
void Menu()
{
    printf("***************************************************************\n");
	printf("***** 1.name                                    2.sex     *****\n");
	printf("***** 3.tele                                    4.addr    *****\n");
	printf("***** 5.age                                     0.exit    *****\n");
	printf("***************************************************************\n");
}

int com_by_name(const void* str1,const void* str2)
{
	return strcmp(((struct people*)str1)->name,((struct people*)str2)->name);
}

int com_by_sex(const void* str1,const void* str2)
{
	return strcmp(((struct people*)str1)->sex,((struct people*)str2)->sex);
}

int com_by_tele(const void* str1,const void* str2)
{
	return strcmp(((struct people*)str1)->tele,((struct people*)str2)->tele);
}

int com_by_addr(const void* str1,const void* str2)
{
	return strcmp(((struct people*)str1)->addr,((struct people*)str2)->addr);
}

int com_by_age(const void* str1,const void* str2)
{
	return ((struct people*)str1)->age - ((struct people*)str2)->age;
}

void SortContact(struct contact* pc)
{
	int input = 0;
	Menu();
    assert(pc != NULL);
again:
	scanf("%d",&input);
	switch(input)
	{
	case 1:
		qsort(pc->data,pc->sz,sizeof(struct people),com_by_name);
		break;
	case 2:
		qsort(pc->data,pc->sz,sizeof(struct people),com_by_sex);
		break;
	case 3:
		qsort(pc->data,pc->sz,sizeof(struct people),com_by_tele);
		break;
	case 4:
		qsort(pc->data,pc->sz,sizeof(struct people),com_by_addr);
		break;
	case 5:
		qsort(pc->data,pc->sz,sizeof(struct people),com_by_age);
		break;
	case 0:
		break;
	default:
		printf("输入错误,请重新输入");
		goto again;
		break;
	}
	if(input == 0)
	{
	    printf("退出排序\n");
	}
	else
	{
	    printf("排序成功\n");
	}
}

void SaveContact(struct contact* pc)
{
	int i = 0;
	//打开文件
	FILE* pfw = fopen("data.txt","wb");
    assert(pc != NULL);
	if(pfw == NULL)
	{
	    perror("SaveContact::fopen");
	}
	//写文件
	for(i=0;i<pc->sz;i++)
	{
	    fwrite(pc->data+i,sizeof(struct people),1,pfw);
	}
	//关闭文件
	fclose(pfw);
	pfw = NULL;
}


test.c文档代码

#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("***** 0.exit                                              *****\n");
	printf("***************************************************************\n");
}
int main()
{
    int input = 0;
	struct contact con;
	InitBoard(&con);
	do
	{
	    menu();
		printf("请选择:>");
		scanf("%d",&input);
		switch(input)
		{
		case 1:
			Addcontact(&con);
			break;
		case 2:
			Delcontact(&con);
			break;
		case 3:
			SearchContact(&con);
			break;
		case 4:
			ModifyContact(&con);
			break;
		case 5:
			ShowContact(&con);
			break;
		case 6:
			SortContact(&con);
			break;
		case 0:
			SaveContact(&con);
			printf("保存文件成功\n");
			DestroyContact(&con);
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	}while(input);
}



contact.h文档代码

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

#define nameMax 20
#define addrMax 30
#define teleMax 12
#define sexMax 3
#define Max 100
#define DEFAULT_INT 3
#define INT_SZ 2

struct people
{
    char name[nameMax];
	char addr[addrMax];
	char tele[teleMax];
	char sex[sexMax];
	int age;
};

struct contact
{
	struct people* data;
	int sz;
	int capacity;
};

//初始化通讯录
void InitBoard(struct contact* pc);

//添加联系人的信息
void Addcontact(struct contact* pc);

//删除联系人的信息
void Delcontact(struct contact* pc);

//搜索联系人的信息
void SearchContact(struct contact* pc);

//修改联系人的信息
void ModifyContact(struct contact* pc);

//显示所有联系人的信息
void ShowContact(struct contact* pc);

//排序联系人的信息
void SortContact(struct contact* pc);

//删除通讯录
void DestroyContact(struct contact* pc);

//加载文件信息的内容到通讯录
void LoadContact(struct contact* pc);

//将通讯录信息加载到文件中
void SaveContact(struct contact* pc);


创建data.txt文档

请添加图片描述
在项目的文件夹寻找,在代码文档中创建一个data.txt文档,存储通讯录信息。



文件版本通讯录的优势

如下面运行图片,我还未输入数据时,并且我正在上一次运行中输入联系人的信息和保存。
请添加图片描述
那我选择显示通讯录信息会发生什么呢?
请添加图片描述
由运行结果可以得知,打印出了联系人的信息。
请添加图片描述
观察data.txt文档可以发现,存储着的联系人的信息(上次运行程序结束时保存的),注意在程序运行时,输入data.txt文档是二进制的,而文本编辑作用于二进制时,只能得出乱码。

这就是文档版本通讯录的功能,让信息不会在程序结束时丢失,但是在实际的应用中,我们不会把程序运行的信息存储在文档中。既不安全效率又低,程序的信息将会存储在数据库中。

今天对于通讯录的分享到此结束,关注点一点,下期更精彩。

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值