动态通讯录+文件存储形式

1.要想实现动态通讯录,我们可以在静态通讯录的基础上加以修改(我前面的博客已写过)

2.然后在动态的基础上加以文件形式保存,每次退出去的时候保存,下次可以读到上次的数据

(1)先写头文件

#ifndef _ADDR_H_          //防止头文件被重复引用
#define _ADDR_H_
enum                     //枚举的优点:防止命名污染,与define比较利于调试,有类型检查,更加严谨,增加代码的可读性和可维护性
{ 
	 EXIT,
	 ADD,
	 SEARCH,
	 DELETE,
	 MOD,
	 SHOW,
	 SORT,
	 EMPTY,

};
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#define MAX_SIZE 3
#define FILENAME "addr.txt"

typedef struct peoinfo
{
	char name[10];
	short  age;
	char sex[5];
	char  addr[10];
}peoinfo;

typedef struct record
{
	peoinfo *elem;
	int sz ;
	int capacity;
}record;

void add(record *p);
void search(record *p);
void show(record *p);
void empty(record *p);
void sort(record *p);
void mod(record *p);
void del(record *p);
record* initrecord();
void loadcontact(record *p);
record *is_full(record *p);
void destroycontact(record * p);
#endif

2.写测试文件

#include"addr.h"

void menu()
{
	printf("***********************************\n");
	printf("****0.exit    1.add     2.search***\n");
	printf("****3.delete  4.mod     5.show  ***\n");
	printf("****6.sort    7.empty           ***\n");
	printf("***********************************\n");
}	

int main()
{
	int input = 0;
	int count = 0;
	record *p ;
	
	p=initrecord();     //初始化
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d",&input);

		switch(input)
		{
		case ADD:
			add(p);
			break;
		case SEARCH:
			search(p);
			break;
		case DELETE:
			 del(p);
			break;
		case MOD:
			mod(p);
			break;
		case SHOW:
			show(p);
			break;
		case SORT:
			sort(p);
			break;
		case EMPTY:
			empty(p);
			break;
		}
	}
		while(input);	
	destroycontact(p);      //销毁
	return 0;
}

3.写函数接口

#include"addr.h"

record *is_full(record *p)       //判断开辟空间是否足够大,不够继续开辟
{
	int n = p->sz;
	if(n == 0||p->sz+3==p->capacity)
	{
		peoinfo *tmp = (peoinfo*)realloc(p->elem,sizeof(peoinfo)*p->capacity);
		if(tmp != NULL)
		{
		    p->elem = tmp;
			p->capacity += 3;
			n = 1;
		}
		else
		{
			perror("realloc");
			exit(EXIT_FAILURE);
		}
	}
	return p;

}
record*initrecord()      //初始化
{
	
	record *s;
	s = (record *)malloc(sizeof(record));
	if(s == NULL)
	{
		perror("malloc");
		exit(EXIT_FAILURE);
	}
	  s->sz = 0;
	  s->capacity = 3;
	  s->elem = NULL;
	  loadcontact(s);
	return s;
}
void loadcontact(record * p)     //读取保存的数据
{
	peoinfo tmp = {0};
	int count = 0;
	FILE *pfread = fopen(FILENAME,"r");
	if(pfread == NULL)
	{
		perror(" open file for read ");
		exit(EXIT_FAILURE);
	}
	   while(fread(&tmp,sizeof(peoinfo),1,pfread))
	   {
		   is_full(p);       //判断空间是够足够来接受
		   p->elem[p->sz] = tmp;
		   p->sz++;
		 
	   }
	fclose(pfread);
	pfread = NULL;
}
void savecontact(record * p)   //退出时,保存数据到FIELNAME文件中
{
	int i = 0;
	FILE *pfwrite = fopen(FILENAME,"w");
	if(pfwrite == NULL)
	{
		perror("open file for write");
		exit(EXIT_FAILURE);
	}
	for (i = 0; i<p->sz; i++)
	{
		fwrite(p->elem+i,sizeof(peoinfo),1,pfwrite);  //用fwrite流来写入
	}
	fclose(pfwrite);
	pfwrite = NULL;
}
void add(record *p)
{
	assert(p!=NULL);
	is_full(p);
	printf("输入姓名:>");
	scanf("%s",&p->elem[p->sz].name);
	printf("输入年龄:>");
	scanf("%d",&p->elem[p->sz].age);
	printf("输入性别:>");
	scanf("%s",&p->elem[p->sz].sex);
	printf("输入地址:>");
	scanf("%s",&p->elem[p->sz].addr);
	p->sz++;
	printf("增加成功\n");
}
static int sea(record *p)  //使函数从具有外部链接属性,变为内部属性
{
	int i = 0;
	char name[10] = {'\0'};
	assert(p!=NULL);

	printf("输入姓名:>");
	scanf("%s",&name);
	for(i=0; i<p->sz; i++)
	{
	if(strcmp(name,(p->elem[i].name))==0)
		return i;
	}
		return -1;
}
void search(record *p)
{
	int i = 0;
	i = sea(p);
	assert(p!=NULL);

	if(i != -1)
	{
		printf("找到了\n");
		printf("姓名:%s,年龄:%d,性别:%s,地址:%s\n",
			p->elem[i].name,
			p->elem[i].age,
			p->elem[i].sex,
			p->elem[i].addr);
	}
	else
		printf("没有找到\n");
}

void show(record *p)
{
	int j = 0;
	assert(p!=NULL);

	printf("姓名    年龄   性别   地址\n");
	for(j=0; j<p->sz; j++)
	{
		printf("%-6s %-6d %-6s %-6s\n",
			p->elem[j].name,
			p->elem[j].age,
			p->elem[j].sex,
			p->elem[j].addr);
	}
}
void empty(record *p)
{
	assert(p!=NULL);
	p->sz = 0;	
}
void del(record *p)
{
	int ret = 0;
	assert(p!=NULL);
	ret = sea(p);
	if(ret != -1||ret<=p->sz)
	{
		int i = 0;
		for(i=ret; i<p->sz-1; i++)
		{
			p->elem[i]=p->elem[i+1];
		}
		p->sz--;
	}
	else
		printf("没有找到联系人\n");

}
void sort(record *p)
{
	int i = 0;
	int j = 0;
	int flag = 0;
	assert(p!=NULL);
	if(p->sz == 0)
		return ;
	for(i=0; i<p->sz-1; i++)
	{
		for(j=0; j<p->sz-1-i; j++)
		{
	   if(strcmp(p->elem[j].name ,p->elem[j+1].name)>0)
	    {
		  peoinfo tmp = p->elem[j];
		  p->elem[j]=p->elem[j+1];
		  p->elem[j+1] = tmp;
		  flag = 1;
	    }
	   if(flag = 0)
		   break;
       }
		  
	}
	printf("排序成功\n");
}
void mod(record *p)
{
	int ret = 0;
	assert(p!=NULL);
	ret = sea(p);
	if(ret!=-1)
	{
		printf("输入要修改的姓名:");
		scanf("%s",&p->elem[ret].name );
		printf("输入要修改的年龄:");
		scanf("%d",&p->elem[ret].age );
		printf("输入要修改的性别:");
		scanf("%s",&p->elem[ret].sex );
		printf("输入要修改的地址:");
		scanf("%s",&p->elem[ret].addr );
		printf("修改成功\n");
	}
	else
		printf("没有找到联系人\n");
	
}
void destroycontact(record * p)   //销毁
{
	 savecontact(p);
	free(p->elem);    //记得释放空间,防止内存泄漏
		p->elem = NULL;
		free(p);
		p = NULL;
}

好了,小伙伴们有什么问题可以给我留言,有什么错误多多包涵,毕竟我也是个新手。


猜你喜欢

转载自blog.csdn.net/congjichukaishi/article/details/80542190