如何 - 从文本文件中读取特定的行集

时间:2011-12-21 16:56:29

标签: c++ file file-io

  

可能重复:
  In C++ is there a way to go to a specific line in a text file?

使用标准C ++库(不选择Boost)从C ++文本文件中读取特定行集(行号A到行号B)的更聪明方法是什么?

2 个答案:

答案 0 :(得分:3)

如果线路长度不固定且您没有索引,则无法比计算\n更好。

考虑这个示例文件:

Hello\nThis is a multi\n-line\nfile, where is this?\n\nAgain?

第1行从字节0开始,第2行从6开始,第3行在22,第4行在28,第5行在49,第6行在50 - 没有模式。

如果我们事先知道这些信息,例如在文件的开头,我们在某个表中得到了这些信息,我们可以计算一个字节偏移到文件中我们关心的行,并使用搜索直接跳转到那里。

如果线宽固定为20个字节:

Hello               \nThis is a multi     \n-line               \nfile, where is this?\n                    \nAgain?

然后我们可以将一条线的起点计算为一个简单的乘法 - 一个偏移到文件中。


如果您正在寻找一种“通用”方式,我会建议:

#include <sstream>
#include <fstream>
#include <iostream>
#include <algorithm>
#include <string>

template <typename Iter, typename Count, typename T>
Iter find_nth(Iter it, const Iter end, Count c, const T match) {
  while(c > 0 && it != end) {
    if (match == *it++)
      --c;
  }
  return it;
}

int main() {
  std::ifstream in("test.txt");
  std::ostringstream str;
  str << in.rdbuf();

  const std::string& s = str.str();
  const int A=2, B=4;
  const std::string::const_iterator begin=find_nth(s.begin(),s.end(), A, '\n');
  const std::string::const_iterator end  =find_nth(begin,s.end(), B-A, '\n');

  const std::string range(begin,end);
  std::cout << range << std::endl;
}

这适用于小型文件(它将整个文件读入std::string)。对于较大的文件,您可能需要执行相同的操作,但使用mmap,使用映射的区域作为迭代器。或者您可以使用在文件中使用RandomAccess的{​​{1}}迭代器来执行此操作。 (seek()不会这样做,它只是std::istream_iterator所以不适合。

答案 1 :(得分:0)

我认为一种方法是计算线条并输出你想要的线条,我认为更好的解决方案是标签,但这就是我如何使它工作,对不起我的noobieness:

在此示例中,我们想要读取包含“Leo 3”的第3行,哦,不要忘记包含库或标题:iostream string fstream

int count;

string lines;
ofstream FileC("file.txt",ios::app);


lines = "Leo \nLeo2 \nLeo3 \n";
FileC << lines;
FileC.close();

ifstream FileR("file.txt");

for(count = 1; count <= 3; count++)
getline(FileR, lines);

cout << lines << endl;

此外,如果你想制作和if语句确保它在我认为的单词之后有空格,因为getline的工作方式:

if(lines == "Leo3 ")
{
    cout << "Yay!";
}