DAY5, 使用read 和 write 实现链表保存到文件,以及从文件加载数据到链表中的功能
题目
使用read 和 write 实现链表保存到文件,以及从文件加载数据到链表中的功能
代码
link.h文件
typedef int DataType;
typedef struct linklist
{
struct
{
DataType data; //普通节点数据域
struct linklist *tail; //头节点数据域
};
struct linklist *next; //指针域,指向下一个节点
// struct linklist *perr; //指针域,指针本节点
}linklist,*linklistPtr;
void TextInit(const char* ch); //文件初始化
linklistPtr load(const char* ch,const linklistPtr H); //从文件中载入数据到链表
linklistPtr CreatLinkList(void); //创建头节点
linklistPtr CreatNode(DataType e); //申请节点 封装数据
void AddData(linklistPtr H,DataType e); //添加数据
void ShowData(const linklistPtr H); //显示链表上的数据
void unload(const char* ch,const linklistPtr H);
link.c文件
#include "link.h"
void TextInit(const char* ch)
{
if(access(ch,F_OK)) //文件不存在
{
int wfp=open(ch,O_WRONLY|O_CREAT,0666); //创建文件并打开
if(-1==wfp)
{
perror("tips:文件不存在,并且文件创建失败\n\n"); //打开失败,则返回
return;
}
int len=0;
write(wfp,&len,sizeof(int)); //写入一个int字节大小数据,记录数据个数
close(wfp); //打开文件,一定要关闭文件
printf("tips:文件不存在,文件新建成功\n\n");
return;
}
printf("tips:文件 %s 存在,无需处理\n\n",ch);
}
linklistPtr load(const char* ch,const linklistPtr H)
{
int rfp=open(ch,O_RDONLY);
if(-1==rfp||NULL==H){return NULL;} //打开文件失败,返回
int len;
DataType e;
read(rfp,&len,sizeof(int)); //读取一个int字节大小数据
for(int i=0;i<len;i++)
{
e=0;
read(rfp,&e,sizeof(DataType)); //循环读取 DataType 字节大小数据
AddData(H,e); //数据载入当前链表
}
close(rfp); //打开文件,一定要关闭文件
printf("tips:文本数据,已载入链表\n\n");
return NULL;
}
void unload(const char* ch,const linklistPtr H)
{
int wfp=open(ch,O_RDWR);
if(-1==wfp||NULL==H){return;}
int len=0;
lseek(wfp,0,SEEK_SET); //光标偏移到文件开头
read(wfp,&len,sizeof(int)); //读取一个int字节大小数据
lseek(wfp,0,SEEK_END); //光标偏移到文件末尾
linklistPtr temp=H; //临时节点,用于遍历链表
while(temp->next!=NULL)
{
temp=temp->next; //成为下一个节点
write(wfp,&temp->data,sizeof(DataType)); //写入数据
len++; //计数
}
lseek(wfp,0,SEEK_SET); //光标偏移到文件开头
write(wfp,&len,sizeof(int));
close(wfp); //打开文件,一定要关闭文件
printf("tips:链表数据,已写入文本\n\n");
}
linklistPtr CreatLinkList(void)
{
//堆区申请
linklistPtr H=(linklistPtr)malloc(sizeof(linklist));
if(NULL==H){return NULL;}
//指针域 赋值 初始值
H->next=NULL;
//数据域 赋值 初始值
H->tail=H;
return H;
}
//申请节点 封装数据
linklistPtr CreatNode(DataType e)
{
//堆区申请
linklistPtr newnode=(linklistPtr)malloc(sizeof(linklist));
if(NULL==newnode){return NULL;}
//指针域 赋值 初始值
newnode->next=NULL;
//数据域 赋值 初始值
newnode->data=e;
return newnode;
}
void AddData(linklistPtr H,DataType e)
{
linklistPtr newnode=CreatNode(e);
if(NULL==newnode||NULL==H){return;}
//原尾节点 指向 本节点
H->tail->next=newnode;
//原尾指针 指向 本节点
H->tail=newnode;
}
void ShowData(const linklistPtr H)
{
if(NULL==H){return;}
linklistPtr temp=H;
printf("tips:当前链表中数据为:");
while(temp->next!=NULL) //下一个节点不为空
{
temp=temp->next; //成为下一个节点
printf("%d ",temp->data); //输出节点内容
}
printf("\n\n");
}
main.c文件
int main(int argc, const char *argv[])
{
//文件初始化
char *ch="link";
TextInit(ch);
//创建链表 头节点
linklistPtr H=CreatLinkList();
//手动添加数据
AddData(H,11);
AddData(H,22);
AddData(H,33);
//显示当前链表上数据
ShowData(H);
// //写入到文件中
unload(ch,H);
// 从文件中载入到链表
load(ch,H);
ShowData(H);
return 0;
}
效果