Bootstrap

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;
}

效果

;