在上一篇文章中,我们实现了动态存储的功能,提升了内存空间的利用率。但是,对于通讯录的数据没有保存功能,这就意味着,我们只能在当前程序中查找到其中的数据,当结束该程序后, 通讯录中的所有数据也就丢失了,再次运行程序,就是一个空通讯录。
显然,这在实际中应用有着不便,我们希望当我们第一次结束程序时,它其中所包含的数据保存住,当我们第二次运行程序时,可以调用到第一次中的数据。
那么,接下来就朝这个目标来实现。
- 既然要保存,那么,我们首先就得创建一个文件,来进行保存操作。
void LoadContact(Contact* pcon)
{
PeoInfo tmp = {0};
FILE* pfRead = fopen("contact.dat", "rb");
if(pfRead == NULL)
{
printf("加载信息:打开文件失败\n");
return;
}
//加载信息
while(fread(&tmp, sizeof(PeoInfo), 1, pfRead))
{
CheckCapacity(pcon);
pcon->data[pcon->sz] = tmp;
pcon->sz++;
}
fclose(pfRead);
pfRead = NULL;
}
- 文件创建好了之后,就可以进行保存操作了。
void SaveContact(Contact* pcon)
{
int i = 0;
FILE* pfWrite = fopen("contact.dat", "wb");
if(pfWrite == NULL)
{
printf("保存信息:打开文件失败\n");
return;
}
//保存信息
for(i=0; i<pcon->sz; i++)
{
fwrite(pcon->data+i, sizeof(PeoInfo), 1, pfWrite);
}
//关闭文件
fclose(pfWrite);
pfWrite = NULL;
}
详细代码
contact.h
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#include<errno.h>
enum Option
{
Exit,
add,
del,
search,
modify,
show,
clear,
sort,
};
#define DEFAULT_SZ 3
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 25
typedef struct Peoinfo
{
char name[NAME_MAX];
int age;
char sex[SEX_MAX];
char tele[TELE_MAX];
char addr[ADDR_MAX];
}Peoinfo;
typedef struct contact
{
struct Peoinfo *data;
int capacity;
int sz;
}contact;
void initcontact(contact* pcon);
void addcontact(contact* pcon);
void delcontact(contact* pcon);
void findcontact(contact* pcon);
void modifycontact(contact* pcon);
void showcontact(const contact* pcon);
void clearcontact(contact* pcon);
void sortcontact(contact* pcon);
void checkcapacity(contact* pcon);
void destroycontact(contact* pcon);
void savecontact(contact* pcon);
void loadcontact(contact* pcon);
contact.c
#include"contact.h"
void loadcontact(contact* pcon)
{
Peoinfo tmp = { 0 };
FILE* pfread = fopen("contact.cyb", "rb");
if (pfread == NULL)
{
printf("打开文件失败\n");
return;
}
while(fread(&tmp, sizeof(Peoinfo), 1, pfread))
{
checkcapacity(pcon);
pcon->data[pcon->sz] = tmp;
pcon->sz++;
}
fclose(pfread);
pfread = NULL;
}
void savecontact(contact* pcon)
{
int i = 0;
FILE* pfwrite = fopen("contact.cyb", "wb");
if (pfwrite == NULL)
{
printf("打开文件失败\n");
return;
}
for (i = 0; i < pcon->sz; i++)
{
fwrite(pcon->data + i, sizeof(Peoinfo), 1, pfwrite);
}
fclose(pfwrite);
pfwrite = NULL;
}
void initcontact(contact* pcon)
{
pcon->data = (Peoinfo *)malloc(DEFAULT_SZ*sizeof(Peoinfo));
if (pcon->data == NULL)
{
return;
}
pcon->sz = 0;
pcon->capacity = DEFAULT_SZ;
loadcontact(pcon);
}
void checkcapacity(contact* pcon)
{
if (pcon->sz == pcon->capacity)
{
Peoinfo* ptr = realloc(pcon->data, (pcon->capacity * 2)*sizeof(Peoinfo));
if (ptr != NULL)
{
pcon->data = ptr;
pcon->capacity *= 2;
printf("增容成功\n");
}
else
{
printf("增容失败\n");
}
}
}
void addcontact(contact* pcon)
{
checkcapacity(pcon);
assert(pcon);
printf("请输入名字:>");
scanf("%s", pcon->data[pcon->sz].name);
printf("请输入年龄:>");
scanf("%d", &(pcon->data[pcon->sz].age));
printf("请输入性别:>");
scanf("%s", pcon->data[pcon->sz].sex);
printf("请输入电话:>");
scanf("%s", pcon->data[pcon->sz].tele);
printf("请输入地址:>");
scanf("%s", pcon->data[pcon->sz].addr);
pcon->sz++;
printf("增加成功\n");
}
static int findbyname(contact* pcon, char name[])
{
int i = 0;
assert(pcon);
for (i = 0; i < pcon->sz; i++)
{
if (0 == strcmp(pcon->data[i].name, name))
{
return i;
}
}
return -1;
}
void delcontact(contact* pcon)
{
int i = 0;
char name[NAME_MAX] = { 0 };
int pos = 0;
assert(pcon);
if (pcon->sz == 0)
{
printf("空通讯录,无法删除\n");
return;
}
printf("请输入要删除的姓名:");
scanf("%s", name);
pos = findbyname(pcon, name);
if (pos == -1)
{
printf("要删除的条目不在\n");
return;
}
for (i = pos; i < pcon->sz; i++)
{
pcon->data[i] = pcon->data[i + 1];
}
pcon->sz--;
printf("删除成功\n");
}
void findcontact(contact* pcon)
{
int i = 0;
char name[NAME_MAX] = { 0 };
int pos = 0;
assert(pcon);
if (pcon->sz == 0)
{
printf("空通讯录,无法删除\n");
return;
}
printf("请输入要删除的姓名:");
scanf("%s", name);
pos = findbyname(pcon, name);
if (pos == -1)
{
printf("要删除的条目不在\n");
return;
}
printf("%15s\t%5d\t%5s\t%12s\t%20s\n",
pcon->data[pos].name,
pcon->data[pos].age,
pcon->data[pos].sex,
pcon->data[pos].tele,
pcon->data[pos].addr);
}
void modifycontact(contact* pcon)
{
int i = 0;
char name[NAME_MAX] = { 0 };
int pos = 0;
assert(pcon);
if (pcon->sz == 0)
{
printf("空通讯录,无法修改\n");
return;
}
printf("请输入要修改的姓名:");
scanf("%s", name);
pos = findbyname(pcon, name);
if (pos == -1)
{
printf("要修改的条目不在\n");
return;
}
printf("请输入要修改的信息(1-姓名,2-年龄,3-性别, 4-电话, 5-地址)");
int msg;
scanf("%d", &msg);
switch (msg)
{
case 1:
printf("请输入要新的姓名:");
scanf("%s", pcon->data[pos].name);
break;
case 2:
printf("请输入要新的年龄:");
scanf("%s", pcon->data[pos].age);
break;
case 3:
printf("请输入要新的性别:");
scanf("%s", pcon->data[pos].sex);
break;
case 4:
printf("请输入要新的电话:");
scanf("%s", pcon->data[pos].tele);
break;
case 5:
printf("请输入要新的地址:");
scanf("%s", pcon->data[pos].addr);
break;
default:
printf("输入有误,修改失败\n");
return;
}
printf("修改成功\n");
}
void showcontact(const contact* pcon)
{
int i = 0;
assert(pcon);
printf("%15s\t%5s\t%5s\t%12s\t%20s\n", "名字", "年龄", "性别", "电话", "地址");
for (i = 0; i < pcon->sz; i++)
{
printf("%15s\t%5d\t%5s\t%12s\t%20s\n", pcon->data[i].name,
pcon->data[i].age,
pcon->data[i].sex,
pcon->data[i].tele,
pcon->data[i].addr);
}
}
void clearcontact(contact* pcon)
{
initcontact(pcon);
}
void sortcontact(contact* pcon)
{
int i, j;
Peoinfo tmp;
for (i = 0; i < pcon->sz - 1; i++)
{
for (j = 0; j < pcon->sz - 1 - i; j++)
{
if (0 < strcmp(pcon->data[j].name, pcon->data[j + 1].name))
{
tmp = pcon->data[j];
pcon->data[j] = pcon->data[j + 1];
pcon->data[j + 1] = tmp;
}
}
}
}
void destroycontact(contact* pcon)
{
free(pcon->data);
pcon->data = NULL;
pcon->capacity = 0;
pcon->sz = 0;
}
test.c
#include"contact.h"
void menu()
{
printf("***************************************\n");
printf("******1. add 2. del **********\n");
printf("******3. search 4. modify **********\n");
printf("******5. show 6. clear **********\n");
printf("******7. sort 0. exit **********\n");
}
int main()
{
int input = 0;
contact con;
initcontact(&con);
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case add:
addcontact(&con);
break;
case del:
delcontact(&con);
break;
case search:
findcontact(&con);
break;
case sort:
sortcontact(&con);
break;
case show:
showcontact(&con);
break;
case clear:
clearcontact(&con);
break;
case Exit:
savecontact(&con);
destroycontact(&con);
printf("退出程序\n");
return 0;
default:
printf("输入有误,请重新输入\n");
break;
}
} while (input);
return 0;
}
- 至此,通过静态存储通讯录—>动态通讯录—>带文件存储的通讯录 这个过程,我们最终实现了比较便捷的实用版本,也许这个过程是我们今后程序生活的所追求的方向,要不断地发现问题,解决问题,从而慢慢提高自己。
*少年,加油吧!!!