2021-09-17 dynamic addres list(File Edition)
}
ps->size = 0;
ps->capacity = SZ;
//把 文件 已经存放的通讯录的信息加载到我们这个通讯录里
LoadContact(ps);
}
[](()接下来我们来看 LoadContact 自定义函数的实现
在这里先给你们把 CheckCapacity 函数 给你们放在这里,后面的 LoadContact 函数会用到,放在这里,方便你们你们理解
void CheckCapacity(struct contact* ps)
{
if (ps->capacity == ps->size)// 存储数据的个数 等于 容量,说明容量满了
{
// 增容
struct people* ptr = (struct people *)realloc(ps->data, (ps->capacity + 2)*sizeof(struct people));
if (!ptr) // ptr == NULL == 0 (开辟失败)为假, !(取反) 变为 1 ,即为真,执行 if 语句
{
printf("增容失败\n");
}
else
{ //开辟成功
ps->data = ptr;// 将 realloc 开辟成功 动态空间的地址赋给 结构体指针比阿娘 data
ps->capacity += 2;// 容量加 2
printf("增容成功\n");
}
}
}
void LoadContact(struct contact* ps)
{
struct people tmp = { 0 };// 创一个相同的类型的结构体变量,用来接收 fread 输入的数据
FILE* pfRead = fopen("contact.data", "rb");// 我们存储联系人的信息 都在 contact.data 文件里
// 现在我们要打开它,打开方式 二进制读取
if (!pfRead)
{
perror("Cause of the file opening failure");
return;
}
// 读取文件,存放通讯录中
while (fread(&tmp, sizeof(struct people), 1, pfRead))// fread 返回 是 无符号数,表示的是 它真实读到的 元素个数
{ // fread 函数 返回值为 0,说明读完了,跳出循环。返回值为 1,读到了一个元素,把这个元素放到通讯录里面
// 但是有可能 通讯录 已经满了,放不下文件的数据,需要扩容
CheckCapacity(ps);// 这里使用 CheckCapacity 函数,来确保它放得下文件的数据
ps->data[ps->size] = tmp;
ps->size++; // 每赋值一个,说明联系人信息 加 一。
}
// 有人可能会有疑问,tmp 的数据会不会一直都是第一个人的信息数据,这个放心是不会的,如果不懂,建议看一下小编的 Operator File 的文章,会让你清晰很多,在读取文件信息的,无论你用的是那种读取方式("r","rb","r+"),在读取完一个数据之后,文件指针 pfRead 会指向下一个数据,你再去读取数据的时候,读取到就是下一个人的数据。所以不用担心,tmp 的数据会保持不变,每一次读取数据,都赋予了 结构体,也就是结构体成员的数据是在变化的。
// 关闭文件
fclose(pfRead);
pfRead = NULL;
}
[](()解决了数据打印的问题,我们再来看看 保存数据到文件里,是怎么做的,不可能只读不写,不写哪来的数据给你读取。
[](()我们为其增添了一个保存信息的功能 Save 功能
![](https://static001.geekbang.org/infoq/2b/2b95ae09fe6c84fd3e94984a9444a72d.png)
![](https://static001.geekbang.org/infoq/a0/a0f8f8133e6fed6f842b9ce91cab1982.png)
现在我们来看 SaveContact 函数功能的实现
![](https://static001.geekbang.org/infoq/95/95d4097ca9fca4e39cbe560f13a37c67.png)
void SaveContact(struct contact* ps)// 保存文件
{
FILE* pf = fopen("contact.data", "wb");// "wb" 写入一个二进制数据到 文件 contact. 《一线大厂 Java 面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 data 中
if (!pf)
{
perror("Cause of the file opening failure");
return ;
}
// 写 通讯录 中 的数据 到文件中
int i = 0;
for (i = 0; i < ps->size; i++)// size 是当前存储了多少个人的信息
{
fwrite(&(ps->data[i]), sizeof(struct people), 1, pf);
// 把 结构体数组 中一个 元素(一个结构体的大小) 写入 文件指针 pf 指向的空间(文件)里。
// 意思就是 从 结构体数组 拿出一个大小为一个结构体(联系人信息的数组)的大小 的 元素 写入 pf 文件指针 指向的空间里
}
printf("保存成功\n");
// 关闭文件
fclose(pf);
pf = NULL;
}
[](()到这里一个动态通讯录(文件版本)就完成了。
评论