打印一個文件的最後n行

問題

命令tail用來打印一個文件的最後n行。其格式爲:
tail [-n] filename
其中:
-n :n表示需要打印的行數,省略時n的值爲10。
filename :給定文件名。
如,命令tail –20 example.txt 表示打印文件example.txt的最後20行。

實現該程序,該程序應具有一定的錯誤處理能力,如能處理非法命令參數和非法文件名。

算法分析

1、如何得到需要打印的行數和文件名?
  使用命令行參數
    int main(int argc, char *argv[])
  行數 n = atoi(argv[1]+1)
  文件名爲 argv[2]
在這裏插入圖片描述
2、如何得到最後n行?
方法一:使用n個節點的循環鏈表。
  首先創建一個空的循環鏈表;
  然後再依次讀入文件的每一行掛在鏈表上,最後鏈表上即爲最後n行。

方法二:使用一個n個元素的指針數組。
  依次讀入每一行,然後循環掛到指針數組上。
    char *lineptr[N]; /存入所讀入的行/
    char *line; /當前讀入行/
    int i; /讀入的行數/

    lineptr[i % n] = (char *)malloc(strlen(line)+1);
    strcpy(lineptr[i%n], line);

方法三:兩次掃描文件。
  第一遍掃描文件,用於統計文件的總行數N;
  第二遍掃描文件時,首先跳過前面N-n行,只讀取最後n行。
  如何開始第二遍掃描?
    fseek(fp, 0, SEEK_SET);

算法實現(循環鏈表)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DEFLINES  10
#define MAXLEN    81
struct Tail {
  char *line;
  struct Tail *next;
};
int main(int argc, char *argv[ ])
{
    char curline[MAXLEN],*filename;
    int n = DEFLINES, i;
    struct Tail *first, *ptr;
    FILE *fp;
    if( argc == 3 && argv[1][0] == '-') {
        n = atoi(argv[1]+1);   //C 庫函數 int atoi(const char *str) 把參數 str 所指向的字符串轉換爲一個整數(類型爲 int 型)。stdlib.h中聲明
        filename = argv[2];
    }
    else if( argc == 2)
        filename = argv[1];
    else {
        fprintf(stderr, "Usage: tail [-n] filename\n");
        return (1);
      }
      
  if((fp = fopen(filename, "r")) == NULL){
      fprintf(stderr, " Cann't open file: %s !\n", filename);
      return (-1);
  }
  first = ptr = (struct Tail *)malloc(sizeof ( struct Tail));
  first->line = NULL;
  for(i=1; i<n; i++){
      ptr->next = (struct Tail *)malloc(sizeof ( struct Tail));
      ptr = ptr->next;
      ptr->line = NULL;
  }
  ptr->next = first;
  ptr = first;
  
  while(fgets(curline, MAXLEN, fp) != NULL){
      if(ptr->line != NULL)
           free(ptr->line);
      ptr->line = (char *) malloc ( strlen(curline)+1);
      strcpy(ptr->line, curline);
      ptr = ptr->next;
  }
  for(i=0; i<n; i++) {
      if(ptr->line != NULL)
          printf("%s",ptr->line);
      ptr = ptr->next;
  }
  fclose(fp);
  return 0;
}


發佈了140 篇原創文章 · 獲贊 149 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章