上一篇中,我们讲了如何自己定义一个负责文件操作的功能集合,今天我们就利用这一组功能完成保存记录的动作。
文件读写操作
在上一篇的基础上,我们稍作修改加入到我们的通讯录工程中来。代码如下:
-
MyFile.h
#ifndef __MY_FILE_H__ #define __MY_FILE_H__ #include <stdio.h> #define FOR_READ 0 #define FOR_WRITE 1 FILE* fp; extern int OpenFile(char* pFileName, int nOperate); extern void CloseFile(); extern char* ReadLine(); extern int WriteLine(char* pLine); #endif
-
MyFile.c
#include "MyFile.h" #include "string.h" #define BUF_SIZE 100 char pBuf[BUF_SIZE]; int OpenFile(char* pFileName, int nOperate) { switch (nOperate) { case FOR_READ: fp = fopen(pFileName, "r"); break; case FOR_WRITE: fp = fopen(pFileName, "w+"); break; default: break; } if (fp == NULL) { return 0; } else { return 1; } } void CloseFile() { fflush(fp); fclose(fp); } char* ReadLine() { pBuf[0] = 0; if(feof(fp)) { return NULL; } else { if (NULL == fgets(pBuf, BUF_SIZE, fp)) { return NULL; } else { pBuf[strlen(pBuf) - 1] = 0; } } return pBuf; } int WriteLine(char* pLine) { fwrite(pLine, sizeof(char), strlen(pLine), fp); fwrite("\n", sizeof(char), 1, fp); return 1; }
注意,这段代码和上一篇中的有所不同,主要是我们在ReadLine()函数的实现中采用了fgets()这个函数。这个函数的特点是读取字符串时遇到换行符会自动停止,与我们的需求比较类似。
数据保存功能
当我们在程序中录入了一些通讯录条目之后,我们需要在退出前将这些数据保存在文件中。在main.c文件中,我们添加一个函数调用,函数名是SavedRecords()。
这个函数实现如下:
void SavedRecords()
{
if (OpenFile("book.txt", FOR_WRITE) != 1)
{
return;
}
ListNode* pNode;
for (pNode = g_pL; pNode->_pR != NULL; pNode = pNode->_pNext)
{
pNode->_pR;
WriteLine(pNode->_pR->_pStrName->pBuf);
WriteLine(pNode->_pR->_pStrTel->pBuf);
WriteLine(pNode->_pR->_pStrPS->pBuf);
WriteLine("----------");
}
CloseFile();
}
这个函数主要执行三个动作:
- 打开一个名为book.txt的文件,注意使用写模式打开
- 遍历链表,之后调用WriteLine()函数把每条记录的每个条目写入book.txt文件
- 关闭文件
在文件中保存数据时,我们用“-----”来分隔不同的记录。就这样,数据保存功能实现了。
数据恢复功能
保存了数据之后,在每次启动程序时,需要重新把这些数据读取出来保存进数据链表中。我们用一个函数LoadRecords()来实现。
在图中程序启动的位置,加入这个函数的调用。具体代码如下:
void LoadRecords()
{
Record* pR = NULL;
if (OpenFile("book.txt", FOR_READ) != 1)
{
return;
}
char* pLine = NULL;
while ((pLine = ReadLine()) != NULL)
{
if (pLine[0] == 0)
{
break;
}
RecordInit(&pR);
RecordSetName(pR, pLine);
pLine = ReadLine();
RecordSetTel(pR, pLine);
pLine = ReadLine();
RecordSetPS(pR, pLine);
pLine = ReadLine();
ListAdd(pR);
}
CloseFile();
}
这段代码也很简单,通过文件操作接口把book.txt文件中的数据读出,填进Record数据结构,之后添加到数据链表中。此时,执行查找方法打印出全部的数据,看看是不是之前的数据都被恢复了呢?
这样,我们一个完整的项目就完成了。
完整的代码请在下面这个路径中获取:https://github.com/breakerthb/TelBook.git
我是天花板,让我们一起在软件开发中自我迭代。
如有任何问题,欢迎与我联系。
上一篇:21天C语言代码训练营(第十五天)
下一篇:21天C语言代码训练营(第十七天)