linux下的tail -n <n>命令的作用就是輸出文本文件的最後n行,如果文件的總行數小於n,則輸出文件的所用行。
其通過C語言的fseek的實現方法如下:
#include <stdio.h> #include <stdlib.h> #define BUFSIZE 256 void myTail(char* filename, unsigned int n) { FILE* f = fopen(filename, "r"); if(!f) { printf("Can not open the file!\n"); return; } fseek(f, -1, SEEK_END); // SEEK_END位置是一個無效的位置,對於文件而言,SEEK_END的前一個位置是文件中最後的那個數據的位置 unsigned int num = 0; while(true) { if(fgetc(f) == '\n') ++num; if(num > n) break; if(fseek(f, -2, SEEK_CUR ) != 0) // 當讀取好一個字符串後,文件的指針會移動到下一個位置上,所以要倒序讀取,此時文件的指針需要向前移動2個字節 { fseek(f, 0, SEEK_SET); // 如果fseek返回值不是零,說明已經到達的文件的頭部,該文件需要從頭全部輸出 break; } } char buffer[BUFSIZE]; while(fgets(buffer, BUFSIZE, f)) // 此處沒有用feof判斷,因爲用feof判斷會導致最後一行輸出兩次,feof是在文件指針失效後,還要讀取一次才判斷爲真 { printf("%s", buffer); } }
上述函數的思路,就是從文件的結尾開始往前讀,讀到的換行符的數量 - 1就是已經經過的行數,需要注意的是,對於一個linux下的文本文件,文件的最後一行即使沒有換行符在最終文件的最後也是有一個換行符的。如下圖,hexdump -C輸出文件的二進制中所描述的那樣
可以看到,無論文件最後是否換行,都會多出一個最後的換行符。