C語言對.CSV檔案從檔案的最後往前一行一行的讀取實現(連結串列實現)
阿新 • • 發佈:2018-12-17
昨天寫過類似的文章:
關於檔案操作,特別是從後往前讀取,要是像上面這篇文章一樣去操作,那效率明顯就太低了,如果一旦資料一多,很難處理。
於是想到了用更好的資料結構來解決這個問題,不就是想從後往前顯示嘛?那麼就可以用連結串列來解決這個問題了。
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檔案的資料:
執行程式得到:
從這裡看到,整個程式就是利用了棧的思想,先進後出,這樣的實現既簡單,也高效。