前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C语言实战小项目——通讯录3.0

C语言实战小项目——通讯录3.0

作者头像
RAIN7
发布2021-08-11 16:31:08
7930
发布2021-08-11 16:31:08
举报

可实现文件保存的通讯录的实现

——接上篇2.0版本动态通讯录的优化3.0版本

C语言实战小项目——通讯录2.0—— 博客入口

一、优化改进部分

  在上次的2.0版本中,我们已经拥有了可实现动态内存操作的通讯录版本,但是每次当我们输入数据,展示数据,退出之后,我们再次执行程序,会发现我们之前输入的联系人信息丢失,需要再次输入。所以,在这次的3.0版本中我们加入了保存联系人信息的功能,这将极大的优化我们对通讯录的使用体验。

具体优化如下:

(1)添加文件保存功能

  1.添加了保存联系人信息的功能,在输入信息后,我们选择保存功能,输入的信息将以文件的信息 (contact.dat) 保存在我们的通讯录的文件夹中。

  保存联系人的信息由 SaveContact 函数具体实现:

代码语言:javascript
复制
void SaveContact(struct Contact *ps)
{

	//创建一个文件pfout 

	FILE * pfout = fopen("contact.dat", "wb");
	if (pfout == NULL)
	{
		printf("文件保存失败\n");
		return;
	}
	

		//写入数据
		int i = 0;
		for (i = 0; i < ps->size; i++)
		{
			fwrite(ps->date + i, sizeof(struct PeoInfor), 1, pfout);
		}
	

	//关闭文件


	fclose(pfout);

	pfout = NULL;

	printf("联系人信息保存成功\n");

}

(2)初始化加载文件信息

  2.打开通讯录程序时,我们在初始化信息的时候,加入 LoadContact 函数,来加载之前保存在“ contact.dat ”文件里的联系人信息。

  在加载信息之前,我们默认存储联系人数量最大是2,如果我们加载的信息大于2个,那么我们需要调整我们的内存空间,用Check_capacity函数来实现判断是否增容以及之后的调整空间操作。

代码语言:javascript
复制
void Check_capacity(struct Contact *ps)
{
	if (ps->size == ps->capacity)
	{
		//增容
		struct PeoInfor * ptr = (struct PeoInfor *)realloc(ps->date, (ps->capacity + 2)*sizeof(struct PeoInfor));
		if (ptr == NULL)
		{
			printf("增容失败\n");
			return;
		}
		else
		{
			ps->date = ptr;
			ps->capacity += 2;
		}
	}

}

void  LoadContact(struct Contact * ps)
{
	FILE * pfin = fopen("contact.dat", "rb");

	if (pfin == NULL)
	{
		printf("加载文件失败\n");
		return;
	}
	
		struct PeoInfor  tmp = { 0 };

		while (fread(&tmp, sizeof(struct PeoInfor), 1, pfin))
		{
			Check_capacity(ps);

			ps->date[ps->size] = tmp;

			ps->size++;
	
	     }

	fclose(pfin);

	pfin = NULL;

}

void InitContact(struct  Contact * ps)
{
	ps->size = 0;
	ps->capacity = DEFAULT_SZ;

	ps->date = (struct PeoInfor *)malloc(DEFAULT_SZ * sizeof(struct PeoInfor));
	if (ps->date == NULL)
	{
		printf("通讯录初始化失败");
		exit(1);
	}

	//加载文件
	LoadContact(ps);

}

二、整体代码展示

1.test.c 通讯录主体框架测试文件

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS 1

#include 
#include "contact.h"
#include 

void menu()
{

	//打印通讯录菜单
	//0.退出菜单
	//1.添加联系人信息
	//2.删除指定名字的联系人信息
	//3.修改联系人的信息
	//4.查找好友的信息
	//5.展示通讯录联系人信息
	//6.对通讯录指定信息进行排序


	printf("*************************************************\n");
	printf("**********  ——欢迎来到通讯录菜单——  *********\n");
	printf("**********      0.退出菜单              *********\n");
	printf("**********      1.添加联系人信息        *********\n");
	printf("*********       2.删除联系人信息        *********\n");
	printf("*********       3.修改联系人信息        *********\n");
	printf("*********       4.查找联系人信息        *********\n");
	printf("*********       5.展示联系人信息        *********\n");
	printf("*********       6.保存联系人信息        *********\n");
	printf("*************************************************\n");
}

//将菜单的功能一一列举出来,以枚举的类型呈现
enum
{
	EXIT,
	ADD,
	DEL,
	MODIFY,
	SEARCH,
	SHOW,
	SAVE
};

int main()
{
	int input = 0;
	//创建通讯录
	struct Contact con;  //Con就是通讯录,里面包含1000个人的信息,及size

	InitContact(&con);

	do
	{
		menu();
		printf("请选择功能:>");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			AddContact(&con);
			break;
		case DEL:
			DelContact(&con);
			break;
		case MODIFY:
			MotifyContact(&con);
			break;
		case SEARCH:
			SearchContact(&con);
			break;
		case SHOW:
			ShowContact(con);
			break;
		case EXIT:
			DestroyContact(&con);
			break;
		case SAVE:
			SaveContact(&con);
			break;
		default:
			printf("选择错误,请重新输入!!\n");
			break;
		}

	} while (input);

	return 0;
}

2.contact.c 通讯录函数文件

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS 1
#include 
#include 
#include "contact.h"
#include 
#include 

void Check_capacity(struct Contact *ps)
{
	if (ps->size == ps->capacity)
	{
		//增容
		struct PeoInfor * ptr = (struct PeoInfor *)realloc(ps->date, (ps->capacity + 2)*sizeof(struct PeoInfor));
		if (ptr == NULL)
		{
			printf("增容失败\n");
			return;
		}
		else
		{
			ps->date = ptr;
			ps->capacity += 2;
		}
	}

}

void  LoadContact(struct Contact * ps)
{
	FILE * pfin = fopen("contact.dat", "rb");

	if (pfin == NULL)
	{
		printf("加载文件失败\n");
		return;
	}
	
		struct PeoInfor  tmp = { 0 };

		while (fread(&tmp, sizeof(struct PeoInfor), 1, pfin))
		{
			Check_capacity(ps);

			ps->date[ps->size] = tmp;

			ps->size++;
	
	     }

	fclose(pfin);

	pfin = NULL;

}



void InitContact(struct  Contact * ps)
{
	ps->size = 0;
	ps->capacity = DEFAULT_SZ;

	ps->date = (struct PeoInfor *)malloc(DEFAULT_SZ * sizeof(struct PeoInfor));
	if (ps->date == NULL)
	{
		printf("通讯录初始化失败");
		exit(1);
	}

	//加载文件
	LoadContact(ps);

}




void AddContact(struct Contact* ps)
{
	Check_capacity(ps);

	printf("请输入姓名:>");
	scanf("%s", ps->date[ps->size].name);
	printf("请输入年龄:>");
	scanf("%d", &(ps->date[ps->size].age));
	printf("请输入性别:>");
	scanf("%s", ps->date[ps->size].sex);
	printf("请输入电话:>");
	scanf("%s", ps->date[ps->size].tel);
	printf("请输入地址:>");
	scanf("%s", ps->date[ps->size].addr);
	ps->size++;
	printf("添加成功\n");


}

void ShowContact(struct Contact ps)
{
	if (ps.size == 0)
	{
		printf("通讯录为空,无法展示\n");
	}
	else
	{
		printf("%10s\t%4s\t%5s\t%12s\t%20s\n", "名字", "年龄", "性别", "电话", "地址");
		int i = 0;
		for (i = 0; i < ps.size; i++)
		{
			printf("%10s\t%4d\t%5s\t%12s\t%20s\n",
				ps.date[i].name,
				ps.date[i].age,
				ps.date[i].sex,
				ps.date[i].tel,
				ps.date[i].addr);
		}
	}
}

void DelContact(struct Contact *ps)
{

	//  查找要删除的人在什么位置,根据名字

	char  name[MAX_name];
	printf("请输入要删除的联系人名字:>");
	scanf("%s", name);
	int i = 0;
	int j = 0;
	//查找名字
	for (i = 0; i < ps->size; i++)
	{
		if (0 == strcmp(name, ps->date[j].name))
		{
			break;
		}
	}

	if (i == ps->size)   // i从循环里出来,strcmp还是不等于0
	{
		printf("未找到该联系人的信息\n");
	}
	else
	{
		for (j = i; j < ps->size; j++)
		{
			ps->date[j] = ps->date[j + 1];

		}
	}
	ps->size--;
	printf("删除成功\n");
}


void MotifyContact(struct Contact *ps)
{
	char  name[MAX_name];
	printf("请输入要删除的联系人名字:>");
	scanf("%s", name);
	int i = 0;
	//查找名字
	for (i = 0; i < ps->size; i++)
	{
		if (0 == strcmp(name, ps->date[i].name))
		{
			break;
		}
	}

	if (i == ps->size)   // i从循环里出来,strcmp还是不等于0
	{
		printf("未找到该联系人的信息\n");
	}
	//表示找到该联系人
	//对下标为i的联系人信息进行修改
	else
	{
		printf("请输入姓名:>");
		scanf("%s", ps->date[i].name);
		printf("请输入年龄:>");
		scanf("%d", &(ps->date[i].age));
		printf("请输入性别:>");
		scanf("%s", ps->date[i].sex);
		printf("请输入电话:>");
		scanf("%s", ps->date[i].tel);
		printf("请输入地址:>");
		scanf("%s", ps->date[i].addr);

	}

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

void SearchContact(struct Contact *ps)
{
	char  name[MAX_name];
	printf("请输入要查找的联系人名字:>");
	scanf("%s", name);
	int i = 0;
	//查找名字
	for (i = 0; i < ps->size; i++)
	{
		if (0 == strcmp(name, ps->date[i].name))
		{
			break;
		}
	}

	if (i == ps->size)   // i从循环里出来,strcmp还是不等于0
	{
		printf("未找到该联系人的信息\n");
	}
	//表示找到该联系人
	//对下标为i的联系人信息进行显示
	else
	{
		printf("%10s\t%4s\t%5s\t%12s\t%20s\n", "名字", "年龄", "性别", "电话", "地址");
		printf("%10s\t%4d\t%5s\t%12s\t%20s\n",
			ps->date[i].name,
			ps->date[i].age,
			ps->date[i].sex,
			ps->date[i].tel,
			ps->date[i].addr);
	}
}

void DestroyContact(struct Contact *ps)
{
	free(ps->date);
	ps->date = NULL;
	ps->size = 0;
	ps->capacity = 0;
}

void SaveContact(struct Contact *ps)
{

	//创建一个文件pfout 

	FILE * pfout = fopen("contact.dat", "wb");
	if (pfout == NULL)
	{
		printf("文件保存失败\n");
		return;
	}
	

		//写入数据
		int i = 0;
		for (i = 0; i < ps->size; i++)
		{
			fwrite(ps->date + i, sizeof(struct PeoInfor), 1, pfout);
		}
	

	//关闭文件


	fclose(pfout);

	pfout = NULL;

	printf("联系人信息保存成功\n");

}

3.contact.h 宏定义及函数声明文件

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS 1

#define MAX 1000
#define MAX_name 20
#define MAX_tel 20
#define MAX_sex 5
#define MAX_addr 30
#define DEFAULT_SZ 2
struct  PeoInfor
{
	char name[MAX_name];
	int age;
	char sex[MAX_sex];
	char tel[MAX_tel];
	char addr[MAX_addr];
};



struct  Contact
{
	struct  PeoInfor* date;  //  存放个人信息
	int size;                 //表示当前通讯录的联系人的数量
	int capacity;
};

// 声明函数
void InitContact(struct  Contact* ps);

void AddContact(struct Contact* ps);

void ShowContact(struct Contact ps);

void DelContact(struct Contact *ps);

void MotifyContact(struct Contact *ps);

void SearchContact(struct Contact *ps);

void DestroyContact(struct Contact *ps);

void SaveContact(struct Contact *ps);

void  LoadContact(struct Contact *ps);

小结

以上 1.0版本——静态通讯录的实现

2.0版本——动态通讯录的实现

3.0版本——可文件保存的通讯录的实现

  较为完整的实现了一个通讯录的大部分功能,当然我们还可以再次进行优化,添加一些更有需要的功能等,我们的C语言实战项目——通讯录到这里就结束了,希望大家可以多多练习,如果有错误,请大家对博主的文章进行指正。

谢谢大家的欣赏与关注!!!

完!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-03-28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 可实现文件保存的通讯录的实现
  • 一、优化改进部分
    • (1)添加文件保存功能
      • (2)初始化加载文件信息
      • 二、整体代码展示
        • 1.test.c 通讯录主体框架测试文件
          • 2.contact.c 通讯录函数文件
            • 3.contact.h 宏定义及函数声明文件
              • 小结
              • 完!
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档