通讯录管理系统之文件版(C语言)

发布于:2022-10-29 ⋅ 阅读:(426) ⋅ 点赞:(0)


学习了C语言的文件操作之后,就可以将我之前写的通讯录管理系统再次进行改造,改造成文件版本,将联系人信息存储到文件当中,这样程序结束之后通讯录信息依旧可以保存。

这是我之前写的两个版本:

通讯录管理系统静态版

通讯录管理系统动态版

下面是需要改变的部分

如果要将通讯录的信息存储到文件中,就要在销毁通讯录、退出通讯录之前进行保存。

1.保存通讯录

我把它封装成一个函数 SaveContact();

void SaveContact(const Con* pc)
{
	//打开文件
	FILE* pf = fopen("contact.txt","wb");
	if (pf == NULL)
	{
		perror("SaveContact::fopen");
		return;
	}
	//写文件
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		fwrite(pc->p+i,sizeof(Peoinfo),1,pf);
	}

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

2.加载通讯录

通讯录创建之后是空的,要把文件中存有的联系人信息导入到通讯录中,所以初始化通讯录函数也需要改造。

//加载函数
void LoadContact(Con* pc) 
{
	//打开文件
	FILE* pf = fopen("contact.txt","rb");
	if (pf==NULL)
	{
		perror("LoadContact::foopen");
		return;
	}
	//读文件
	Peoinfo tmp = { 0 };
	while (fread(&tmp, sizeof(Peoinfo), 1, pf))
	{
		//加载进来的时候空间可能不够,所以涉及到增容
		CheckCapcity(pc);
		pc->p[pc->sz] = tmp;
		pc->sz++;
	}

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


//文件版本
void InitContact(Con* pc)
{
	assert(pc);
	pc->sz = 0;
	pc->capcity = START_SZ;
	pc->p = (struct Peoinfo*)malloc(pc->capcity * sizeof(struct Peoinfo));
	if (pc->p == NULL)
	{
		perror("InitContact::malloc");
		return;
	}
	memset(pc->p, 0, pc->capcity * sizeof(struct Peoinfo));
	//加载文件信息到通讯录中
	LoadContact(pc);
}

效果展示

此时文件里已经有了信息,启动程序之后,不用添加,选择打印,就可以将存储的信息打印出来

在这里插入图片描述

代码展示(分文件)

1.test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"


void menu()
{
	printf("             通讯录\n");
	printf("*************************************\n");
	printf("****** 1、Add     2、Del    *********\n");
	printf("****** 3、Modify  4、Search *********\n");
	printf("****** 5、Print   6、Sort   *********\n");
	printf("****** 0、Exit              *********\n");
	printf("*************************************\n");

}
void test()
{
	int input = 0;
	struct Contact con;
	//初始化通讯录
	InitContact(&con);

	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case add:
			AddContact(&con);
			break;
		case del:
			DelContact(&con);
			break;
		case modify:
			Modify(&con);
			break;
		case search:
			Search(&con);
			break;
		case print:
			Print(&con);
			break;
		case sort:
			Sort(&con);
			break;
		case Exit:
			SaveContact(&con);
			DestroyContact(&con);
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}



	} while (input);

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

2.contact.h

#pragma once

#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 13
#define ADDR_MAX 30
#define People_MAX 1000

//通讯录初始化默认空间大小
#define START_SZ 3
//类型声明

typedef struct Peoinfo//每个人的信息
{
	char name[NAME_MAX];
	char sex[SEX_MAX];
	int age;
	char tele[TELE_MAX];
	char addr[ADDR_MAX];
}Peoinfo;

typedef struct Contact
{
	struct Peoinfo* p;//指向动态开辟内存空间
	int sz;//记录存放在通讯录中的人数
	int capcity;//记录开辟的空间的当前最大容量
}Con;

//通讯录功能
enum fun
{
	Exit,
	add,
	del,
	modify,
	search,
	print,
	sort
};

enum modifyoption//修改信息选项
{
	Name = 1,
	Sex,
	Age,
	Tele,
	Addr
};


//函数声明
 

//初始化通讯录
void InitContact(Con* pc);

//增加联系人
void AddContact(Con* pc);
//打印
void Print(const Con* pc);
//删除联系人
void DelContact(Con* pc);
//查找
int FindByName(const Con* pc,char* name);
//查找联系人
void Search(const Con* pc);
//修改联系人信息
void Modify(Con* pc);
//排序
void Sort(Con* pc);
//增容
void CheckCapcity(Con* pc);
//销毁通讯录
void DestroyContact(Con* pc);


//文件版本
//保存通讯录
void SaveContact(const Con* pc);

3.contact.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "contact.h"

//静态版
//void InitContact(Con* pc) 
//{
//	assert(pc);
//	pc->sz = 0;
//	memset(pc->p,0,sizeof(pc->p));
//}

//动态版
//void InitContact(Con* pc) 
//{
//	assert(pc);
//	pc->sz = 0;
//	pc->capcity = START_SZ;
//	pc->p = (struct Peoinfo*)malloc(pc->capcity*sizeof(struct Peoinfo));
//	if (pc->p == NULL)
//	{
//		perror("InitContact::malloc");
//		return;
//	}
//	memset(pc->p, 0, pc->capcity * sizeof(struct Peoinfo));
//
//}
// 


void LoadContact(Con* pc) 
{
	//打开文件
	FILE* pf = fopen("contact.txt","rb");
	if (pf==NULL)
	{
		perror("LoadContact::foopen");
		return;
	}
	//读文件
	Peoinfo tmp = { 0 };
	while (fread(&tmp, sizeof(Peoinfo), 1, pf))
	{
		//加载进来的时候空间可能不够,所以涉及到增容
		CheckCapcity(pc);
		pc->p[pc->sz] = tmp;
		pc->sz++;
	}

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


//文件版本
void InitContact(Con* pc)
{
	assert(pc);
	pc->sz = 0;
	pc->capcity = START_SZ;
	pc->p = (struct Peoinfo*)malloc(pc->capcity * sizeof(struct Peoinfo));
	if (pc->p == NULL)
	{
		perror("InitContact::malloc");
		return;
	}
	memset(pc->p, 0, pc->capcity * sizeof(struct Peoinfo));
	//加载文件信息到通讯录中
	LoadContact(pc);
}

void CheckCapcity(Con* pc)
{
	if (pc->sz == pc->capcity)
	{
		Peoinfo* tmp = (Peoinfo*)realloc(pc->p, (pc->capcity + 2) * sizeof(Peoinfo));//每次增加2个
		if (tmp != NULL)
		{
			pc->p = tmp;
		}
		pc->capcity += 2;
		printf("增容成功\n");
	}
}

//释放动态开辟的空间
void DestroyContact(Con* pc)
{
	free(pc->p);
	pc->p = NULL;
	pc->capcity = 0;
	pc->sz = 0;
	printf("销毁成功\n");
}

void AddContact(Con* pc)
{
	assert(pc);
	//静态版本
	/*if (pc->sz == People_MAX)
	{
		printf("通讯录已满,无法增加\n");
		return;
	}*/
	//动态版本   满了要增容
	CheckCapcity(pc);

	printf("请输入名字:");
	scanf("%s", pc->p[pc->sz].name);
	printf("请输入性别:");
	scanf("%s", pc->p[pc->sz].sex);
	printf("请输入年龄:");
	scanf("%d", &(pc->p[pc->sz].age));
	printf("请输入电话:");
	scanf("%s", pc->p[pc->sz].tele);
	printf("请输入住址:");
	scanf("%s", pc->p[pc->sz].addr);

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


void Print(const Con* pc)
{
	assert(pc);
	//打印
	int i = 0;
	printf("%-20s %-5s %-10s %-13s %-30s\n", "名字", "性别", "年龄", "电话", "住址");
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s %-5s %-10d %-13s %-30s\n", pc->p[i].name, pc->p[i].sex, pc->p[i].age, pc->p[i].tele, pc->p[i].addr);
	}

}

void DelContact(Con* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录已空,无法删除\n");
		return;
	}
	//要删除,首先要找到删除的对象
	char name[NAME_MAX] = { 0 };
	printf("请输入要查找的名字:");
	scanf("%s", name);
	int ret = FindByName(pc,name);//找到返回下标,找不到返回-1
	if (ret == -1)
	{
		printf("找不到\n");
		return;
	}
	else
	{
		//删除-->把后面的数据覆盖到要删除的地方
		int i = 0;
		for (i = ret; i < pc->sz-1; i++)
		{
			pc->p[i] = pc->p[i + 1];
		}
		pc->sz--;
		printf("删除成功\n");
		return;
	}
}

int FindByName(const Con* pc,char* name)
{
	assert(pc);
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->p[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}

void Search(const Con* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录是空的,找不到\n");
		return;
	}
	//找
	char name[NAME_MAX] = { 0 };
	printf("请输入要查找的名字:");
	scanf("%s", name);
	int ret = FindByName(pc, name);
	if (ret == -1)
	{
		printf("找不到\n");
		return;
	}
	else
	{
		//找到并打印
		printf("%-20s %-5s %-10s %-13s %-30s\n", "名字", "性别", "年龄", "电话", "住址");
		printf("%-20s %-5s %-10d %-13s %-30s\n", pc->p[ret].name, pc->p[ret].sex, pc->p[ret].age, pc->p[ret].tele, pc->p[ret].addr);
		return;
	}
}

void Modify(Con* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录是空的,无法修改\n");
		return;
	}
	//先找到指定目标
	char name[NAME_MAX] = { 0 };
	printf("请输入要修改的联系人的名字:");
	scanf("%s", name);
	int ret = FindByName(pc, name);
	//修改
	char sex[SEX_MAX] = { 0 };
	char tele[TELE_MAX] = { 0 };
	char addr[ADDR_MAX] = { 0 };
	int age = 0;
	if (ret == -1)
	{
		printf("找不到\n");
		return;
	}
	else
	{
		//找到打印显示,并修改
		int input = 0;
		printf("%-20s %-5s %-10s %-13s %-30s\n", "名字", "性别", "年龄", "电话", "住址");
		printf("%-20s %-5s %-10d %-13s %-30s\n", pc->p[ret].name, pc->p[ret].sex, pc->p[ret].age, pc->p[ret].tele, pc->p[ret].addr);
		printf("------------------------------\n");
		printf("%s %s %s %s %s\n", "1、名字", "2、性别", "3、年龄", "4、电话", "5、住址");
		printf("请选择要修改的信息:");//定义一个修改信息选项的枚举
		scanf("%d", &input);
		switch (input)
		{
		case Name:
			printf("请输入修改信息:");
			scanf("%s", name);
			memcpy(pc->p[ret].name, name, NAME_MAX);
			printf("修改成功\n");
			printf("%-20s %-5s %-10s %-13s %-30s\n", "名字", "性别", "年龄", "电话", "住址");
			printf("%-20s %-5s %-10d %-13s %-30s\n", pc->p[ret].name, pc->p[ret].sex, pc->p[ret].age, pc->p[ret].tele, pc->p[ret].addr);
			break;
		case Sex:
			
			printf("请输入修改信息:");
			scanf("%s", sex);
			memcpy(pc->p[ret].sex, sex, SEX_MAX);
			printf("修改成功\n");
			printf("%-20s %-5s %-10s %-13s %-30s\n", "名字", "性别", "年龄", "电话", "住址");
			printf("%-20s %-5s %-10d %-13s %-30s\n", pc->p[ret].name, pc->p[ret].sex, pc->p[ret].age, pc->p[ret].tele, pc->p[ret].addr);
			break;
		case Age:
			printf("请输入修改信息:");
			scanf("%d", age);
			memcpy(pc->p[ret].age, age,sizeof(int));
			printf("修改成功\n");
			printf("%-20s %-5s %-10s %-13s %-30s\n", "名字", "性别", "年龄", "电话", "住址");
			printf("%-20s %-5s %-10d %-13s %-30s\n", pc->p[ret].name, pc->p[ret].sex, pc->p[ret].age, pc->p[ret].tele, pc->p[ret].addr);
			break;
		case Tele:
			printf("请输入修改信息:");
			scanf("%s", tele);
			memcpy(pc->p[ret].tele, tele, TELE_MAX);
			printf("修改成功\n");
			printf("%-20s %-5s %-10s %-13s %-30s\n", "名字", "性别", "年龄", "电话", "住址");
			printf("%-20s %-5s %-10d %-13s %-30s\n", pc->p[ret].name, pc->p[ret].sex, pc->p[ret].age, pc->p[ret].tele, pc->p[ret].addr);
			break;
		case Addr:
			printf("请输入修改信息:");
			scanf("%s", addr);
			memcpy(pc->p[ret].addr, addr, ADDR_MAX);
			printf("修改成功\n");
			printf("%-20s %-5s %-10s %-13s %-30s\n", "名字", "性别", "年龄", "电话", "住址");
			printf("%-20s %-5s %-10d %-13s %-30s\n", pc->p[ret].name, pc->p[ret].sex, pc->p[ret].age, pc->p[ret].tele, pc->p[ret].addr);
			break;
		default:
			break;
		}
		return;
	}
}

static void SortMenu()
{
	printf("*************************\n");
	printf("*** 1、名字   2、年龄 ***\n");
	printf("*************************\n");
}

static int cmp_by_name(const void* e1,const void* e2)
{
	return strcmp((((struct Peoinfo*)e1)->name), ((struct Peoinfo*)e2)->name);
}

static int cmp_by_age(const void* e1, const void* e2)
{
	return (((struct Peoinfo*)e1)->age)-((struct Peoinfo*)e2)->age;

}


void Sort(Con* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录是空的,无法排序\n");
		return;
	}
	//排序  用qsort
	int input = 0;
	SortMenu();
	printf("请选择排序的方式:");
	scanf("%d", &input);
	switch (input)
	{
	case 1:
		qsort(pc->p,pc->sz,sizeof(struct Peoinfo),cmp_by_name);
		printf("排序成功\n");
		break;
	case 2:
		qsort(pc->p, pc->sz, sizeof(struct Peoinfo), cmp_by_age);
		printf("排序成功\n");
		break;
	default:
		printf("选择错误\n");
		break;
	}
}

void SaveContact(const Con* pc)
{
	//打开文件
	FILE* pf = fopen("contact.txt","wb");
	if (pf == NULL)
	{
		perror("SaveContact::fopen");
		return;
	}
	//写文件
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		fwrite(pc->p+i,sizeof(Peoinfo),1,pf);
	}

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

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到