牛骨文教育服务平台(让学习变的简单)
博文笔记

C语言对.CSV文件从文件的最后往前一行一行的读取实现(链表实现)

创建时间:2018-10-24 投稿人: 浏览次数:603
版权声明:本文为博主原创文章,如有需要,请注明转载地址:http://blog.csdn.net/morixinguan。若是侵权用于商业用途,请联系博主,否则将追究责任 https://blog.csdn.net/morixinguan/article/details/83344951

昨天写过类似的文章:

https://blog.csdn.net/morixinguan/article/details/83309576

关于文件操作,特别是从后往前读取,要是像上面这篇文章一样去操作,那效率明显就太低了,如果一旦数据一多,很难处理。

于是想到了用更好的数据结构来解决这个问题,不就是想从后往前显示嘛?那么就可以用链表来解决这个问题了。

typedef struct links
{
	int size  ; 
	void *ptr ; 
	struct links *next ;
	struct links *pre  ;
}LINKS;

     这是链表的数据结构,ptr就是要存放的数据,pre是前驱指针,next是后继指针,通过这两个指针,即可以方便实现链表的遍历。

    下面定义要实现的函数:

typedef  void (*print_t)(void *Data)  ; 
void print(void *Data);
//打印链表节点
void   print_links(LINKS *Header , print_t  func);
//创建链表头
LINKS  *Create_Links_Header(int size);
//头插
void  top_append(LINKS *Header , void *Data , int size);
//获取文件总行数
int GetTotalLineCount(FILE *file);

整体实现:

#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#define  NR(x)   (sizeof(x)/sizeof(x[0]+0))

typedef struct links
{
	int size  ; 
	void *ptr ; 
	struct links *next ;
	struct links *pre  ;
}LINKS;

typedef  void (*print_t)(void *Data)  ; 
void print(void *Data);
void   print_links(LINKS *Header , print_t  func);
LINKS  *Create_Links_Header(int size);
void  top_append(LINKS *Header , void *Data , int size);
int GetTotalLineCount(FILE *file);


int main(void)
{
	int line = 0 ;
	int file_all_line = 0 ;
	char line_buffer[50] = {0};
	LINKS *Header = NULL ;
	//1.初始化链表 
	Header =  Create_Links_Header(0);
	if(NULL == Header)
	{
		fprintf(stderr , "malloc  Header fail 
");
		return -1 ; 
	}
	//2.插入数据 
	FILE *fp = NULL ;
	fp = fopen("1.csv","r");
	if(NULL == fp)
	{
		printf("open csv file fail!
");
		return -1 ;
	}
	//移到文件头 
	fseek(fp,0,SEEK_SET);
	//获取文件的总行数 
	file_all_line = GetTotalLineCount(fp);
	for(line = 0 ; line < file_all_line ; line++)
	{
		if(fgets(line_buffer,50,fp))	
		{
			printf("line_buffer:%s",line_buffer);
			top_append(Header , line_buffer , 100);
		}
	}
	print_links(Header,print);
	fclose(fp);
	free(Header);
	return 0 ;
}

void print(void *Data)
{
	printf("%s" ,Data);
	//这里可以进行数据处理...
	
	//这里可以进行数据处理...
}
//打印链表节点
void print_links(LINKS *Header , print_t func)
{
	LINKS *tmp = Header->next ; 

	while(tmp != Header)
	{
		func(tmp->ptr);
		tmp = tmp->next ;
	}
}
//获取文件的总行数
int GetTotalLineCount(FILE *file)
{   
	int line_num = 0;
	char strLine[50];
	fseek(file,0,SEEK_SET);
	while (fgets(strLine, 50, file))
		line_num++;
	fseek(file,0,SEEK_SET);
	return line_num;
}
//创建表头
LINKS  *Create_Links_Header(int size)
{
	LINKS *New = NULL  ; 
	
	New = malloc(sizeof(LINKS));
	if(NULL == New)
	{
		fprintf(stderr , "malloc LINKS header fail 
");
		return NULL ; 
	}

	New->size = size ; 
	New->ptr = NULL ; 
	
	New->next = New ;
	New->pre  = New ; 

	return New ;
}
//链表头插
void  top_append(LINKS *Header , void *Data , int size)
{
	LINKS *New = NULL ; 
	
	New = malloc(sizeof(LINKS));
	if(NULL == New)
	{
		fprintf(stderr , "malloc links fail 
");
		return ;
	}
	
	New->ptr=NULL ;
	New->size = size ; 

	New->ptr = malloc(size);
	if(NULL == New->ptr)
	{
		fprintf(stderr , "malloc links data fail 
");
		return ; 
	}
	memcpy(New->ptr , Data , size);
	New->next = Header->next ; 
	New->pre  = Header ; 
	New->next->pre = New ;  
	New->pre->next = New ; 
}



运行结果:

如下图所示为excel文件的数据:

运行程序得到:

从这里看到,整个程序就是利用了栈的思想,先进后出,这样的实现既简单,也高效。

声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。