如果行长不固定,并且您没有索引,那么您不能比计算\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 所以不合适)。