1. 程式人生 > >C語言對.CSV檔案從檔案的最後往前一行一行的讀取實現(連結串列實現)

C語言對.CSV檔案從檔案的最後往前一行一行的讀取實現(連結串列實現)

昨天寫過類似的文章:

關於檔案操作,特別是從後往前讀取,要是像上面這篇文章一樣去操作,那效率明顯就太低了,如果一旦資料一多,很難處理。

於是想到了用更好的資料結構來解決這個問題,不就是想從後往前顯示嘛?那麼就可以用連結串列來解決這個問題了。

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 \n");
		return -1 ; 
	}
	//2.插入資料 
	FILE *fp = NULL ;
	fp = fopen("1.csv","r");
	if(NULL == fp)
	{
		printf("open csv file fail!\n");
		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 ;
        free(tmp->pre);
	}
}
//獲取檔案的總行數
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 \n");
		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 \n");
		return ;
	}
	
	New->ptr=NULL ;
	New->size = size ; 

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



執行結果:

如下圖所示為excel檔案的資料:

執行程式得到:

從這裡看到,整個程式就是利用了棧的思想,先進後出,這樣的實現既簡單,也高效。