contract.h
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>
#define cst 3
#define nameMax 20
#define sexMax 10
#define teleMax 15
#define addrMax 20
typedef struct peoForm
{
char name[nameMax];
int age;
char sex[sexMax];
char tele[teleMax];
char addr[addrMax];
}peoForm;
typedef struct contract//通讯录类型
{
struct peoForm *data;
int size;
int capacity;
}contract;
enum option//利用枚举
{
Exit,//0
add,//1
del,
search,
modify,
show,
sort,
save
};
void initContract(struct contract* ps);//通讯录初始化声明
void addConstract(struct contract* ps);//通讯录增加函数声明
void showConstract(struct contract* ps);//通讯录显示打印函数声明
void delConstract(struct contract* ps);//删除通讯录元素的函数声明
void searchConstract(const struct contract* ps);//查找通讯录元素的函数声明
void modifyConstract(struct contract* ps);//修改通讯录元素的函数声明
void sortConstractByName(struct contract* ps);//对通讯录元素进行排序的函数声明
void saveConstract(struct contract* ps);//对通讯录的元素进行存储
void destoryConstract(contract* ps);//对通讯录的动态内存进行销毁
void loadContract(struct contract* ps);//对contract.dat文件里的内容进行加载
contract.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"contract.h"
void initContract(struct contract* ps)
{
ps->data=(struct peoForm*)malloc(cst*sizeof(struct peoForm));
if(ps->data==NULL)
{
return ;
}
ps->size=0;
ps->capacity=cst;
loadContract(ps);
}//定义动态通讯录初始化
void checkCapacity(struct contract* ps)//检查通讯录并且扩容
{
struct peoForm* str=NULL;
if(ps->capacity==ps->size)
{
struct peoForm* str = (struct peoForm* )realloc(ps->data,(ps->capacity+2)*sizeof(struct peoForm));
if(str!=NULL)
{
ps->data=str;
ps->capacity+=2;
printf("增容成功\n");
}
else
{
printf("增容失败\n");
}
}
}
void addConstract(struct contract* ps)//通讯录增加函数定义
{
checkCapacity(ps);//检测通讯录容量。满了,增容;不满,什么都不干
printf("请输入姓名\n");
scanf("%s",ps->data[ps->size].name);
printf("请输入年龄\n");
scanf("%d",&(ps->data[ps->size].age));
printf("请输入性别\n");
scanf("%s",ps->data[ps->size].sex);
printf("请输入电话\n");
scanf("%s",ps->data[ps->size].tele);
printf("请输入地址\n");
scanf("%s",ps->data[ps->size].addr);
ps->size++;
printf("添加成功\n");
}
void showConstract(struct contract* ps)//定义通讯录打印函数
{
if(ps->size==0)
{
printf("通讯录为空\n");
}
else
{
int i=0;
printf("%-20s\t%-5s\t%-10s\t%-15s\t%-20s\t\n","姓名","年龄","性别","电话","地址");
for(i=0;i<ps->size;i++)
{
printf("%-20s\t%-5d\t%-10s\t%-15s\t%-20s\t\n"
,ps->data[i].name
,ps->data[i].age
,ps->data[i].sex
,ps->data[i].tele
,ps->data[i].addr);
}
}
}
static int findName(const struct contract* ps,char name[nameMax])//封装查找姓名的函数,防止代码冗余
{
int i=0;
for(i=0;i<ps->size;i++)
{
if(0==strcmp(ps->data[i].name,name))//strcmp:str1=str2,相等,则返回0。
{
return i;
}
}
return -1;
}
void delConstract(struct contract* ps)//删除通讯录元素的函数定义
{
char name[nameMax];
int pos;
printf("请输入想要删除的人的姓名\n");
scanf("%s",name);
pos=findName(ps,name);
if(pos==-1)
{
printf("没找到要删除的人\n");
}
else
{
int j=0;
for(j=pos;j<ps->size-1;j++)
{
ps->data[j]=ps->data[j+1];
}
ps->size--;
printf("删除成功\n");
}
}
void searchConstract(const struct contract* ps)//搜索通讯录元素的函数定义
{
char name[nameMax];
int pos;
printf("请输入你想查找的姓名\n");
scanf("%s",name);
pos=findName(ps,name);
if(pos==-1)
{
printf("没找到要查找的人\n");
}
else
{ printf("%-20s\t%-5s\t%-10s\t%-15s\t%-20s\t\n","姓名","年龄","性别","电话","地址");
printf("%-20s\t%-5d\t%-10s\t%-15s\t%-20s\t\n"
,ps->data[pos].name
,ps->data[pos].age
,ps->data[pos].sex
,ps->data[pos].tele
,ps->data[pos].addr);
}
}
void modifyConstract(struct contract* ps)//修改通讯录元素的函数的定义
{
char name[nameMax];
int pos;
printf("请输入要修改的姓名");
scanf("%s",name);
pos=findName(ps,name);
if(pos==-1)
{
printf("没找到要修改的人\n");
}
else
{
printf("请输入姓名\n");
scanf("%s",ps->data[pos].name);
printf("请输入年龄\n");
scanf("%d",&(ps->data[pos].age));
printf("请输入性别\n");
scanf("%s",ps->data[pos].sex);
printf("请输入电话\n");
scanf("%s",ps->data[pos].tele);
printf("请输入地址\n");
scanf("%s",ps->data[pos].addr);
printf("修改成功\n");
}
}
int cmpByName(const void* e1,const void* e2)
{
return strcmp(((struct contract*)e1)->data->name,((struct contract*)e2)->data->name);
}
void sortConstractByName(struct contract* ps)//对通讯录的元素按照姓名进行排序的函数定义
{
int len=ps->size;
qsort(ps->data,len,sizeof(ps->data[0]),cmpByName);
}
void saveConstract(struct contract* ps)//把输入的信息以二进制的新式存储到contract.dat的文件中
{
FILE* pf=fopen("contract.dat","wb");
int i=0;
if(pf==NULL)
{
printf("saveConstract:%s\n",strerror(errno));
return ;
}
for(i=0;i<ps->size;i++)
{
fwrite(&(ps->data[i]),sizeof(peoForm),1,pf);
}
fclose(pf);
ps=NULL;
}
void destoryConstract(contract* ps)//释放动态内存
{
free(ps->data);
ps->data=NULL;
}
void loadContract(struct contract* ps)//读取contract.dat文件的内容
{
FILE* pf=fopen("contract.dat","rb");
struct peoForm temp={0};
int i=0;
if(pf==NULL)
{
printf("loadContract:%s\n",strerror(errno));
return ;
}
while(fread(&temp,sizeof(peoForm),1,pf))
{
checkCapacity(ps);
ps->data[ps->size]=temp;
ps->size++;
}
fclose(pf);
pf=NULL;
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"contract.h"
void menu()
{
printf("*********************************\n");
printf("*** 1:add 2:del ***\n");
printf("*** 3:search 4:modify ***\n");
printf("*** 5:show 6:sort ***\n");
printf("*** 7:save 0:exit ***\n");
printf("*********************************\n");
}
int main()
{
int input=0;
struct contract con;
initContract(&con);//初始化通讯录
do
{
menu();
printf("请选择模式\n");
scanf("%d",&input);
switch(input)
{
case add:addConstract(&con);
break;
case del:delConstract(&con);
break;
case search:searchConstract(&con);
break;
case modify:modifyConstract(&con);
break;
case show:showConstract(&con);
break;
case sort:sortConstractByName(&con);
break;
case save:saveConstract(&con);
break;
case Exit:saveConstract(&con);
destoryConstract(&con);
printf("退出程序\n");
break;
default:printf("请输入正确的数字\n");
break;
}
}while(input);
}