如何从C ++的最后一行读取文本文件?

时间:2014-07-14 15:28:18

标签: c++ ifstream

我有一个这样的文本文件:

1    0.05   -7  
2    0.1    -4  
3    0.11   -1   
4    0.12   -3   
3    0.15   -2
4    0.2    0  
5    0.25   8

我要找的是从最后一行读取C ++中的文本文件,到达以4开头的行,将该行的值保存在数组中,然后继续到达以2开头的行并再次保存与此行对应的值。

从最后一行开始对我来说非常重要,因为我查找时间步骤4的最后更新值。 当我正在寻找这个向量4 0.12 -3

时,从头开始阅读会给我这个向量4 0.2 0

4 个答案:

答案 0 :(得分:2)

实现这一点真的不是一件轻而易举的事。除非文件非常庞大(100MGB或更多),否则最好的方法可能就是将整个内容简单地读入一个向量中,并在内存中处理它[以您选择的顺序排列,因为您现在可以将其视为任何向量输入它,因此"随机访问"]。

有可能从末尾向后移动,但它很尴尬。像这样的东西会从后到前读取整个文件:

ifstream f("somefile.txt");
char c;
// Place get position at one from last. 
f.seekg(-1, ios_base::end);
while(f.get(c))
{
  ... process character ... 
  // Move back two (because get moved forward one, and
  // we want the one before that. 
  f.seekg(-2, ios_base::cur);
}

然后你必须记住你的字符串是向后的,所以你必须先添加而不是追加。

答案 1 :(得分:1)

我的点操作策略是逐行扫描所有文件,在内存中保留两行数组,在每个传入行更新,以便始终包含最新的两行。在EOF,您的数组包含感兴趣的行。 伪代码:

array[2];
array[0]=array[1]=null;
while(!eof)
{
   array[1]=array[0];
   array[0]=readline();
}

... do what you want with array[1] and array[0]

array[0]将包含文件的最后一行array[1],但最后一行。 check for null:如果文件只包含一行,或者根本没有行,则可以让数组中的一个或两个条目指向null。 当然,如果文件的大小非常大,那么这是一个非常昂贵的时间,但它是一种简单可靠的解决方案,适用于每个操作之间至少有几分钟数量级的现场操作。 否则,如果需要更频繁的轮询,为什么不继续监视文件? 这是tail -f程序使用的策略。

答案 2 :(得分:0)

在文本文件中跳转很困难,而且通常非常低效。我建议如下:

  1. 将整个文件加载到内存中,仅保留最新结果:

    ifstream fin("fname.txt");
    
    // ... Don't forget error checking.
    
    std::unordered_map<int, std::pair<float, int>> entries;
    int first, third;
    float second;
    while (fin >> first >> second >> third) {
       entries[first] = make_pair(second, third); // Will overwrite existing.
    }
    
  2. 现在,只需访问您要查找的密钥的地图,即可轻松访问最后一个条目。

    cout << entries[4]->first << " " << entries[4]->second  << endl;
    
  3. 输出:0.2 0

答案 3 :(得分:0)

我想到了两种策略:

1 - 之前提出的:有大小为2或两个变量的数组等...,以保存最后两行读取(如果文件很小,应该非常好用,并且非常直接)

2 - 使用ifstream :: seekg(std :: ios_base :: end)定位在EOF中,然后向后搜索EOL标记(如果文件较大且行与文件相比较小,则应该有效)。使用peek可以检查EOL标记(考虑到不同的EOL标记(\ n \ r,\ n,\ r),这会更复杂,如果行变长则可能会慢。