通讯录(文件版)

之前已经发过静态版的通讯录了,动态版的其实思路也和静态版的差不多,这里不再多说,今天想在这里说的是文件版通讯录 ,这个其实大体思路还是和前面的静态版的差不多,我们先看看代码:

#pragma once
#include
#include
#include
#include
#define MAX_NAME 10
#define MAX_ADDR 20
#define MAX_SEX 7
#define MAX_TELE 12
//#define DILATION 4





typedef struct contact
{
	char name[MAX_NAME];
	char addr[MAX_ADDR];
	char sex[MAX_SEX];
	char tele[MAX_TELE];
	int age;
}contact;




//静态通讯录
//typedef struct addressing
//{
//	contact* pa;
//	int sz;
//}addressing;




//动态版通讯录
typedef struct addressing
{
	contact* pa;
	int sz;
	int capacity;
}addressing;





void init(addressing* p);
void add(addressing* p);
void del(addressing* p);
void show(addressing con);
void find(addressing con);
void amend(addressing* p);
void empty(addressing* p);
void sort_name(addressing* p);
void savecontact(addressing* p);
void loadcontact(addressing* p);
#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
void init(addressing* p)
{
	assert(p);
	p->sz = 0;
	p->pa = (contact*)malloc(sizeof(contact) * 2);
	assert(p->pa);
	p->capacity = 2;
}
void add(addressing* p)
{
	if (p->sz == p->capacity)
	{
		//开始扩容
		contact* tem = (contact*)realloc(p->pa, sizeof(contact) * p->capacity * 2);
		assert(tem);
		p->pa = tem;
		p->capacity = 2 * p->capacity;
		printf("扩容成功\n");
	}
	else
	{
		printf("请输入要添加的用户姓名\n");
		scanf("%s", p->pa[p->sz].name);
		printf("请输入要添加的用户地址\n");
		scanf("%s", p->pa[p->sz].addr);
		printf("请输入要添加的用户性别\n");
		scanf("%s", p->pa[p->sz].sex);
		printf("请输入要添加的用户电话\n");
		scanf("%s", p->pa[p->sz].tele);
		printf("请输入要添加的用户年龄\n");
		scanf("%d", &(p->pa[p->sz].age));
		p->sz++;
		printf("添加成功\n");
	}
}
void del(addressing* p)
{
	if (0 == p->sz)
	{
		printf("通讯录为空,操作异常\n");
		exit(-1);
	}
	else
	{
		printf("请输入要删除的用户的姓名\n");
		char name[MAX_NAME] = { 0 };
		scanf("%s", name);
		int i = 0;
		int ret = 0;
		for (i = 0; i < p->sz; i++)
		{
			if (0 == strcmp(name, p->pa[i].name))
			{
				ret = 1;
				memmove(&(p->pa[i]), &(p->pa[i + 1]), sizeof(contact) * (p->sz - 1 - i));
				p->sz--;
				printf("删除用户成功\n");
				break;
			}
		}
		if (0 == ret)
		{
			printf("要删除的用户不存在\n");
		}
	}
}
void show(addressing con)
{
	if (con.sz == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	else
	{
		int i = 0;
		for (i = 0; i < con.sz; i++)
		{
			printf("姓名:%s\n", con.pa[i].name);
			printf("地址:%s\n", con.pa[i].addr);
			printf("性别:%s\n", con.pa[i].sex);
			printf("电话:%s\n", con.pa[i].tele);
			printf("年龄:%d\n", con.pa[i].age);
		}
	}
}
void find(addressing con)
{
	if (con.sz == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	printf("请输入要查找的用户姓名\n");
	char name[MAX_NAME] = { 0 };
	scanf("%s", name);
	int i = 0;
	int ret = 0;
	for (i = 0; i < con.sz; i++)
	{
		if (0 == strcmp(name, con.pa[i].name))
		{
			ret = 1;
			printf("已找到用户\n");
			break;
		}
	}
	if (0 == ret)
	{
		printf("通讯录中没有查找的用户\n");
	}
}
void amend(addressing* p)
{
	if (p->sz == 0)
	{
		printf("通讯录为空,操作异常\n");
		exit(-1);
	}
	printf("请输入要修改的用户姓名\n");
	char name[MAX_NAME] = { 0 };
	scanf("%s", name);
	int i = 0;
	int ret = 0;
	for (i = 0; i < p->sz; i++)
	{
		if (0 == strcmp(name, p->pa[i].name))
		{
			ret = 1;
			printf("请输入要添加的用户姓名\n");
			scanf("%s", p->pa[p->sz - 1].name);
			printf("请输入要添加的用户地址\n");
			scanf("%s", p->pa[p->sz - 1].addr);
			printf("请输入要添加的用户性别\n");
			scanf("%s", p->pa[p->sz - 1].sex);
			printf("请输入要添加的用户电话\n");
			scanf("%s", p->pa[p->sz - 1].tele);
			printf("请输入要添加的用户年龄\n");
			scanf("%d", &(p->pa[p->sz - 1].age));
			printf("修改成功\n");
			break;
		}
	}
	if (ret == 0)
	{
		printf("要修改的用户不存在\n");
	}
}
void empty(addressing* p)
{
	p->sz = 0;
	printf("通讯录已清空\n");
}
static int cmp(const void* e1, const void* e2)
{
	return ((addressing*)e1)->pa->name - ((addressing*)e2)->pa->name;
}
void sort_name(addressing* p)
{
	if (p->sz == 0)
	{
		printf("通讯录为空,不需要排序\n");
		return;
	}
	else
	{
		qsort(p->pa, p->sz, sizeof(contact), cmp);
		printf("排序成功\n");
	}
}
void savecontact(addressing* p)
{
	assert(p);
	FILE* pf = fopen("contact.txt", "w");
	if (pf == NULL)
	{
		perror("write->fopen");
		exit(-1);
	}
	int i = 0;
	for (i = 0; i < (p->sz); i++)
	{
		fprintf(pf, "%s %s %s %s %d ", (p->pa[i]).name, (p->pa[i]).addr, (p->pa[i]).sex, (p->pa[i]).tele, (p->pa[i]).age);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
}
void loadcontact(addressing* p)
{
	assert(p);
	//打开文件
	FILE* pf = fopen("contact.txt", "r");
	if (pf == NULL)
	{
		perror("read->fopen");
		exit(-1);
	}
	//把文件信息读取到内存
	contact t = { 0 };
	while ((fscanf(pf, "%s %s %s %s %d", t.name, t.addr, t.sex, t.tele, &(t.age))) != EOF)
	{
		if (p->sz == p->capacity)
		{
			//开始扩容
			contact* tem = (contact*)realloc(p->pa, sizeof(contact) * p->capacity * 2);
			assert(tem);
			p->pa = tem;
			p->capacity = 2 * p->capacity;
			printf("扩容成功\n");
		}
		p->pa[p->sz] = t;
		p->sz++;
		
	}
	//判断是遇到错误停止还是已经到文件末尾
	if (feof(pf))
	{
		printf("文件读取到末尾,正常结束\n");
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
}
#define _CRT_SECURE_NO_WARNINGS 1
#define _CRT_SECURE_NO_WARNINGS 1
#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
enum en
{
	EXIT,
	ADD,
	DEL,
	FIND,
	AMEND,
	SHOW,
	EMPTY,
	SORT_NAME
};
void menu()
{
	printf("**********************************\n");
	printf("******1.ADD            2.DEL******\n");
	printf("******3.FIND           4.AMEND****\n");
	printf("******5.SHOW           6.EMPTY****\n");
	printf("******7.SORT_NAME      0.EXIT ****\n");
	printf("**********************************\n");
}
int main()
{
	int input = 0;
	addressing con;
	init(&con);
	loadcontact(&con);
	do
	{
		menu();
		printf("请选择\n");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			add(&con);
			break;
		case DEL:
			del(&con);
			break;
		case FIND:
			find(con);
			break;
		case AMEND:
			amend(&con);
			break;
		case SHOW:
			show(con);
			break;
		case EMPTY:
			empty(&con);
			break;
		case SORT_NAME:
			sort_name(&con);
			break;
		case EXIT:
			savecontact(&con);
			printf("已保存好通讯录信息\n");
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
	return 0;
}

这里就是文件版的所有的代码了,其实相当于静态版的,就新加了两个函数,一个是加载信息,一个是保存信息,保存信息放在退出通讯录的那里是因为,原先我们的信息都是在内存中存储的,程序一结束,就把空间返回给系统了,所以我们就在想,有没有什么能够保存我们通讯录里的信息,这里刚好文件就是我们需要的,所以,我就在退出通讯录的时候,把信息全部保存到文件中,然后下次再次运行的时候,就把文件里面的信息再次读取到内存,这样不就好了吗?所以就加了这两个函数

总体思路还是不变,唯一不同的是,这个可以长期存放信息,但是静态版的不行。希望大家多多支持!

你可能感兴趣的:(平时练习篇,c++,java,算法)