方法一:快慢指针法,和找链表倒数第K个节点有点类似。同样适用两个文件指针,fp,fs,把快的文件指针先读N行后,快慢文件指针同时一行一行的开始读取,直到快的文件指针读到文件最后,则慢的文件指针此时读到文件的倒数第N行,就可以开始数数慢的文件指针的内容直到读取文件结束。
代码实现如下:
1 void PrintfFileN(string filename,int n){ 2 File* fp,*fs; 3 int i; 4 char fpline[MAXLINE]; 5 char fsline[MAXLINE]; 6 if((fp = fopen(filename,"r")) == NULL) 7 { 8 fprintf(stderr,"Cannot open file:%s/n",filename); 9 exit(-1); 10 } 11 12 if((fs = fopen(filename,"r")) == NULL) 13 { 14 fprintf(stderr,"Cannot open file:%s/n",filename); 15 exit(-1); 16 } 17 18 for(i = 1;i <= n; i++) 19 fgets(fpline,MAXLEN,fp); //先将fp移动n个位置 20 21 while(fgets(fpline,MAXLEN,fp) != NULL) 22 fgets(fsline,MAXLEN,fs); //将fp与fq一起向尾部移动,直到fp指向末尾 23 24 //此时fq指向倒数第n行 25 while(fgets(fsline,MAXLEN,fs) != NULL) 26 printf("%s",fsline); //输出从fq开始的每一行 27 }
方法二:利用循环链表。设置链表的长度为n,节点的data为char型数组,用来保存一行的内容。首先打开文件,读取一行,将这行的内容拷贝到循环链表当前指针所指的节点中,然后把链表指针后移,重复读取,拷贝,结束后,链表中节点就保存了文件倒数N行的内容。
1 typedef struct Node{ 2 char Data[MAXLINE]; 3 struct Node * next; 4 }Node; 5 void PrintfFileN(string filename,int N){ 6 Node* list=NULL,*p=NULL,*temp; 7 char fileData[MAXLINE]; 8 File* pFile; 9 int i=0; 10 while(i<N){//建个一个头结点是list的长度为N的链表 11 if(list==NULL){ 12 list=p=(Node*)malloc(sizeof(Node)); 13 list->Data[0]='\0'; 14 list->next=NULL; 15 i++; 16 }else{ 17 temp= (Node*)malloc(sizeof(Node)); 18 temp->data[0]='\0'; 19 temp->next=NULL; 20 p->next=temp; 21 p=temp; 22 i++; 23 } 24 } 25 p->next=list;//循环链表 26 p=list; 27 pFile=fopen(filename,"r"); 28 while(gets(fileData,MAXLINE,pFile)!=NULL){ 29 strcpy(p->Data,fileData); 30 p=p->next; 31 } 32 for(i=0;i<N;i++){ 33 temp=p->next; 34 printf("%s",p->data); 35 free(p); 36 p=temp; 37 } 38 }