之前已经发过静态版的通讯录了,动态版的其实思路也和静态版的差不多,这里不再多说,今天想在这里说的是文件版通讯录 ,这个其实大体思路还是和前面的静态版的差不多,我们先看看代码:
#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;
}
这里就是文件版的所有的代码了,其实相当于静态版的,就新加了两个函数,一个是加载信息,一个是保存信息,保存信息放在退出通讯录的那里是因为,原先我们的信息都是在内存中存储的,程序一结束,就把空间返回给系统了,所以我们就在想,有没有什么能够保存我们通讯录里的信息,这里刚好文件就是我们需要的,所以,我就在退出通讯录的时候,把信息全部保存到文件中,然后下次再次运行的时候,就把文件里面的信息再次读取到内存,这样不就好了吗?所以就加了这两个函数
总体思路还是不变,唯一不同的是,这个可以长期存放信息,但是静态版的不行。希望大家多多支持!