打印一个文件的最后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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章