目录
前言:
对于我们之前利用动态内存实现的通讯录来说,存在一个严重的问题。
就是当我们的程序运行结束,此时我们在通讯录所添加的全部联系人信息会全部丢失。
通过上一篇blog的学习,我们知道程序的数据是在内存中运行,当程序结束时,系统就会自动收回我们程序开辟好的空间,里面的数据也就随之丢失。
那我们在这里,我们想要实现一种通讯录,我们在这个通讯录创建的联系人全部不会丢失。
这就不得不使用我们已经学习了的操作------------------文件操作。
通讯录的实现可以访问以下链接:
文件操作的讲解可以访问以下链接:
接下来我们就通过我们之前写过的通讯录代码进行改进操作,
代码可以访问我的Gitee仓库:
test_c_with_X1: 本仓库里的代码为c语言的测试代码 - Gitee.com
保存联系人
我们想要将我们已经添加的联系人保存到文件中,代码如下:
cpp
void SaveContact(Contact* pc)
{
assert(pc);
char ch = 0;
FILE* pf = fopen("Contact.txt", "wb");
if (pf == NULL)
{
perror("SaveContact");
return;
}
//写数据
for (int i = 0; i < pc->sz; i++)
{
fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);
}
//关闭文件
fclose(pf);
pf = NULL;
}
我们在这里用二进制的方式来输入和输出,
所以在这里fopen里面应当是"wb"
这里就是将程序的数据写到pf打开的文件夹中。
这个位置应当放置在退出程序函数中,并且在清除通讯录前
cppcase EXIT: //保存信息到文件中 SaveContact(&con); DestoryContact(&con); printf("正在退出...\n"); break;
当运行结束时,文件夹的数据如图所示:
读取联系人:
cpp
static void LoadContact(Contact* pc)
{
assert(pc);
PeoInfo tmp = { 0 };
char ch = 0;
FILE* pf = fopen("Contact.txt", "rb");
if (pf == NULL)
{
perror("LoadContact");
return;
}
//读文件
while (fread(&tmp, sizeof(PeoInfo), 1, pf))
{
Check_capacity(pc);
pc->data[pc->sz] = tmp;
pc->sz++;
}
//关文件
fclose(pf);
pf = NULL;
}
这里要注意的是,我们在讲文件里的数据写到程序时,
可能会出现文件中的联系人超过capacity,即联系人数量sz >通讯录此时容量capacity,
所以我们最好在将文件数据传入到程序中先调用Check_capacity函数,
并且在传入数据时要一个联系人一个联系人的传输,每次传输完后就将pc->sz++
这样当我们传输完第三个联系人时,pc->sz就会==capacity,这样我们就需要增容。
这里因为我们是用的while循环,如果我们不创建临时的接受变量tmp,则当sz==2时,进入下一次循环,直接将第四个联系人传入到程序中。
可是此时capacity==3,因此还来不及调用Check_capacity,如此一来,程序就会崩溃。
因此我们应当创建tmp这个临时变量,并且在自增前使用它!
总结:
以上就是利用文件操作实现通讯录的改进操作。
如果你对之前的通讯录的实现十分熟练,相信你一定可以很好掌握此次讲解。
记住
"坐而言不如起而行"
Action speak louder than words!
以下是我的Gitee仓库,可以访问此完整代码: