欢迎来到 Claffic 的博客 💞💞💞
前言:
上期通讯录我们实现了动态内存的申请,但数据依然是存放在内存中,当程序退出的时候,通讯录中的数据自然就不存在了,等下次运行通讯录程序的时候,数据又得重新录入。
这一期继续改造,让通讯录更加实用,能够实时保存练习人信息。
1.实时保存如何实现?
这就涉及到了数据持久化的问题:
一般 数据持久化的方法有:把数据存放在磁盘文件、存放到数据库等方式。
2. 相关函数介绍
2.1 fopen
fopen 函数的作用是打开指定的文件;
返回值:
如果打开文件成功,返回指向要打开文件的文件指针;
如果打开文件失败,返回 NULL;
所以函数的返回值要做检查;
传参:
filename : 要打卡文件的名称(包含后缀);
mode : 使用的方式,yi
2.2 fclose
很直观,作用是关闭文件;
返回值:
如果关闭成功,返回 0;
如果关闭失败,返回 EOF;
传参:
指向要关闭文件的文件指针;
使用文件,养成好习惯:
打开文件 --> 相关操作 --> 关闭文件
#include<stdio.h>
void File(Test* pc)
{
FILE* pf = fopen("test.txt", "rb");
//检查返回值
if (pf == NULL)
{
perror("Test");
return;
}
//操作...
//关闭文件
fclose(pf);
pf = NULL;
}
2.3 fread
fread 作用是将文件中的信息读取到一块内存缓冲区中;
返回值:
实际从文件中读取的基本单元个数;
传参:
ptr : 将文件中的二进制数据读取到的缓冲区;
size : 一次读取的基本单元大小,单位是字节;
count : 一次读取的单元个数;
stream : 文件指针,指向要读取的文件。
2.4 fwrite
fwrite 作用是 把数据写入文件中;返回值:实际从内存中写入文件的 基本单元个数;传参:与 fread 类似,将读取改为写入。
3.实现过程
void Save_Contact(Contact* pc)
{
FILE* pf = fopen("contact.txt", "wb");
if (pf == NULL)
{
perror("Save_Contact");
}
else
{
//写入数据
int i = 0;
for (i = 0; i < pc->sz; i++)
{
fwrite(pc->data+i, sizeof(PeoInform), 1, pf);
}
fclose(pf);
pf = NULL;
printf("保存成功\n");
}
}
这一部分用到了 fwrite 函数,将数据写入文件中。
加载通讯录部分:
void Load_Contact(Contact* pc)
{
FILE* pf = fopen("contact.txt", "rb");
if (pf == NULL)
{
perror("Load_Contact");
}
else
{
//读数据
PeoInform tmp = { 0 };
int i = 0;
while (fread(&tmp, sizeof(PeoInform), 1, pf))
{
check_capacity(pc);
pc->data[i] = tmp;
pc->sz++;
i++;
}
fclose(pf);
pf = NULL;
}
}
这一部分主体上用 fread 函数来实现,读取文件中的数据;
巧妙的是:
直接将 fread 的返回值作为 while 循环的判断条件:
因为每次只读一个单位的数据,读取成功返回 1 ,到了文件末尾,读取不到数据了,就返回 0 ,跳出循环。
源码已上传至 我的gitee
拿走不谢 ~
总结:
本次通讯录的升级应用到了文件操作的相关知识,掌握了文件操作,数据持久化就不是问题啦 ~