gpt4 book ai didi

c++ - 如何使用 ifstream (C++) 只读取一些以前知道的行

转载 作者:太空狗 更新时间:2023-10-29 20:36:15 24 4
gpt4 key购买 nike

通过对文件进行预处理,我找到了一些需要进一步处理的行,知道我想阅读这些行。有没有比使用 ifstream::getline(...) 逐行读取更快的解决方案?

例如,我知道我只需要产品行 4 (0-4-8-12-16-...) 或存储在 vector 中的特殊行号...

现在我正在这样做:

string line;
int counter = 0;
while( getline(ifstr,line) ){
if(counter%4 =0){
// some code working with line
}
}

但我想要这样的东西(如果更快的话)

while(getline(ifstr,line)){ 
// some code working with line
while(++counter%4 !=0){ // or checking on index vector
skipline(ifstr)
}
}

让我再次提一下,我有一些行索引(已排序但不是这个常规索引),但为了简单起见,我使用了这个 product4 示例。

编辑:我想跳到开头的行,例如我知道我需要从第 2000 行开始读取,如何快速跳过 1999 行?谢谢大家

最佳答案

因为@caps 说这让他觉得标准库中没有任何东西可以帮助完成这种任务,所以我觉得有必要证明其他情况:)

Live On Coliru

template <typename It, typename Out, typename Filter = std::vector<int> >
Out retrieve_lines(It begin, It const end, Filter lines, Out out, char const* delim = "\\n") {
if (lines.empty())
return out;

// make sure input is orderly
assert(std::is_sorted(lines.begin(), lines.end()));
assert(lines.front() >= 0);

std::regex re(delim);
std::regex_token_iterator<It> line(begin, end, re, -1), eof;

// make lines into incremental offsets
std::adjacent_difference(lines.begin(), lines.end(), lines.begin());

// iterate advancing by each offset requested
auto advanced = [&line, eof](size_t n) { while (line!=eof && n--) ++line; return line; };

for (auto offset = lines.begin(); offset != lines.end() && advanced(*offset) != eof; ++offset) {
*out++ = *line;
}

return out;
}

这明显更通用。权衡(目前)是标记化迭代器需要随机访问迭代器。我发现这是一个很好的权衡,因为文件上的“随机访问”无论如何都需要内存映射文件

现场演示 1:从字符串到 vector<string>

Live On Coliru

int main() {
std::vector<std::string> output_lines;
std::string is(" a b c d e\nf g hijklmnop\nqrstuvw\nxyz");

retrieve_lines(is.begin(), is.end(), {0,3,999}, back_inserter(output_lines));

// for debug purposes
for (auto& line : output_lines)
std::cout << line << "\n";
}

打印

 a b c d e
xyz

现场演示 2:从文件到 cout

Live On Coliru

#include <boost/iostreams/device/mapped_file.hpp>
int main() {
boost::iostreams::mapped_file_source is("/etc/dictionaries-common/words");

retrieve_lines(is.begin(), is.end(), {13,784, 9996}, std::ostream_iterator<std::string>(std::cout, "\n"));
}

打印例如

ASL's
Apennines
Mercer's

The use of boost::iostreams::mapped_file_source can easily be replaced with straight up ::mmap but I found it uglier in the presentation sample.

关于c++ - 如何使用 ifstream (C++) 只读取一些以前知道的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39317617/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com