C++实现tail的方法(还不完善)

本文介绍了一种从文件尾部高效读取指定行数内容的算法实现,通过逐步增加向前查找的字符数量来确保读取到足够的行数,适用于日志等应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基本思想是,从文件末尾向前Seek N个字符,读入内存,如果达到了tail n行则读取结束,如果不够n行再从文件末尾向前Seek N+N*2^1个字符,并读取N*2^1个字符,加上之前的行数,如果还不够tail n行,继续直到N+N*2^1+...+N*2^m以满足tail n为止。

 

#include <iostream> #include <fstream>
#include
<string>
#include
<list>

int tail(const std::string & fname, std::list<std::string> & ls, int lines, int bytes=100)
{
    std::fstream fs(fname.c_str());
   
if(!fs)
       
return -1;
   
   
int status=0;
   
    fs.seekg(
0,std::ios_base::end);
    std::streamoff old_pos
=fs.tellg();
    std::streamoff last_pos
=old_pos-bytes*lines;
    fs.seekg(last_pos,std::ios_base::beg);
       
    std::
string line;
    std::list
<std::string>::const_iterator cit=ls.begin();
   
while(true)
    {
        std::getline(fs,line);
        cit
=ls.insert(cit,line);
       
++cit;
       
if(status==0)
        {
           
if(fs.eof())
            {
               
if(ls.size()>lines)
                   
break;
                old_pos
=last_pos;
                last_pos
>>=1;
                fs.clear();
                fs.seekg(last_pos,std::ios_base::beg);
                std::streamoff temp
=fs.tellg();
                ls.erase(
--cit);
                cit
=ls.begin();
                status
=1;
            }
        }
       
else if(status > 0)
        {
           
if(fs.tellg() >= old_pos)
            {
               
if(ls.size() > lines)
                   
break;
                old_pos
=last_pos;
                last_pos
>>=1;
                fs.seekg(last_pos,std::ios_base::beg);
                ls.erase(
--cit);
                cit
=ls.begin();
            }
        }
    }
   
   
if(ls.size()>lines)
    {
       
int i=ls.size()-lines;
       
for(;i>0;--i)
            ls.erase(ls.begin());
    }
   
return ls.size();
}
   
int main(int argc, char * argv[])
{
    std::list
<std::string> ls;
  tail(argv[
1],ls,atoi(argv[2]));
  std::copy(ls.begin(),ls.end(),std::ostream_iterator
<std::string>(std::cout,"/n"));
 
return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值