【问题标题】:How to - Read specific set of lines from a text file [duplicate]如何 - 从文本文件中读取特定的行集 [重复]
【发布时间】:2011-12-21 16:56:28
【问题描述】:

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

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

【问题讨论】:

  • 而不是从头开始读取文件以匹配那些行号以提取文本..!
  • 我假设它在您逐行处理时手动计算行数,仅消耗从 A 到 B 的行
  • @Vignesh:没有比这更聪明的方法了。除非您没有告诉我们更多信息,否则您所能做的就是猜测 A 行和 B 行的开始位置。
  • 如果行不是固定长度并且您没有某种索引,那么您最好从头开始读取整个文件并计数\ns
  • @awoodland 是的。行的长度不是固定的。

标签: c++ file file-io


【解决方案1】:

如果行长不固定,并且您没有索引,那么您不能比计算\ns 做得更好。

考虑这个示例文件:

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 行开始 - 没有模式。

如果我们事先知道该信息,例如在文件的开头,我们在某个表中拥有该信息,我们可以为我们关心的行计算文件中的字节偏移量,并使用 seek 直接跳转到那里。

如果行宽固定为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 代替,使用映射区域作为迭代器。或者您可以使用在文件中使用seek()RandomAccess 迭代器来执行此操作。 (std::istream_iterator 不这样做,它只是一个ForwardIterator 所以不合适)。

【讨论】:

  • @Vignesh - 我用一个从 A 行和 B 行之间读取的通用方式的示例对其进行了更新。
  • 我得到了这个想法并且非常好,现在我必须尝试使用​​地图(对于更大的文件)。再次,非常感谢。
【解决方案2】:

我认为一种方法是计算行数并输出您想要的行,我认为更好的解决方案是标签,但这就是我的工作方式,对不起我的菜鸟:

在本例中,我们要读取包含“Leo 3”的第 3 行,哦,别忘了包含库或标题:iostreamstringfstream

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!";
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-25
    • 1970-01-01
    相关资源
    最近更新 更多