//author: jvk
#include <stdio.h>
#include <string.h>
int main(int argc,char *argv[])
{
FILE *fp;
int beg,count=10,i=0;
char ch,line[100];
fp = fopen(argv[1], "r");
//to hold the begining of the file
beg = ftell(fp);
//read file backwards
fseek(fp,0,SEEK_END);
// moving file pointer such that it points to at begining of last
ten lines of file
while(count && ftell(fp)!= beg)
{
ch = getc(fp);
if(ch=='\n')
{
count--;
}
i--;
//moving backwards.
fseek(fp,i,SEEK_END);
}
//printing from current position of fp.
while(fgets(line,sizeof(line),fp) != NULL)
{
printf("%s",line);
}
fclose(fp);
return 0;
}
5条答案
按热度按时间voase2hg1#
我不认为有什么解决方案不同于“向前阅读数据时保留最新的N行”或“从末尾开始向后读取,直到读取第N行”。
关键是你会根据上下文使用一个或另一个。
当tail访问一个随机访问文件时,或者当数据小到足以放入内存时,“走到最后并向后”更好。在这种情况下,运行时间最小化,因为您扫描了必须输出的数据(因此,它是“最优的”)
你的解决方案(保留N个最新的行)是更好的,当尾巴是由管道或当数据是巨大的。在这种情况下,另一个解决方案浪费太多的内存,所以它是不切实际的,在这种情况下,源比尾巴慢(这是可能的)扫描所有的文件并不那么重要。
jum4pzuy2#
从文件末尾向后读取,直到读取到
N
换行符或到达文件开头。然后打印刚才读取的内容。
我认为这里不需要任何花哨的数据结构。
如果你感兴趣的话。
vcirk6k63#
首先使用
fseek
找到文件的结尾,然后减去512和fseek
到那个偏移量,然后从那里向前读到结尾。计算换行符的数量,因为如果太少,你将不得不用减去的偏移量1024**...做同样的事情,但是在99%的情况下512就足够了。这(1)避免了向前阅读整个文件,并且(2)**这可能比从末尾向后读取更有效的原因是向前读取通常更快。
rkttyhzu4#
/
*This example implements the option n of tail command.*/
bjp0bcyl5#