从包含 m 行的文件中取出 n 行,必要时(懒惰地)重复该文件

Taking n lines from a file which contains m lines, repeating the file (lazily) if necessary

我正在寻找一种方法来使用文本文件生成所需的文本,只需根据需要重复几次即可。

在像 Haskell 这样的纯函数式语言中,解决方案似乎微不足道:here 我已经发布了审查代码,它很短,尽管我很漂亮当然可以改进。

但在 C++ 中,我几乎不知道从哪里开始,只是我很确定 Boost Hana 提供了很多我设计解决方案所需的工具。

这是一个示例输入文件,

line 1
line 2
line 3

而且,如果我要求 7 行,这就是我想放入变量中的内容(例如在带有嵌入式 '\n's 的单个 std::string 中),

line 1
line 2
line 3
line 1
line 2
line 3
line 1

我想这个函数可以有这样的声明:

std::string function(std::string s, int n);

要在 C++ 中执行此操作,您需要类似于以下内容的循环:

std::string readLines(std::string filename, int nlines)
{
    std::ifstream in(filename);
    std::string line, result;

    while (nlines > 0)
    {
        while (std::getline(in, line))
        {
            result += line;
            result += '\n';
            if (--nlines == 0)
                return result;
        }

        if (!in) // an error occurred...
            break; // or throw...

        // must be eof, rewind and start over...

        in.clear(); // <-- seekg() clears eofbit in C++11 and later...

        if (!in.seekg(0)) // an error occurred...
            break; // or throw...
    }

    return result;
}

假设 file 是一些输入流,并且您想将 file 中的行重复 n 行,您可以像这样使用 range-v3 库:

namespace rv = ranges::views;

auto lines = ranges::getlines(file) 
           | ranges::to<std::vector<std::string>>;
  
auto result = lines 
            | rv::cycle
            | rv::take(n) 
            | rv::join('\n') 
            | ranges::to<std::string>;

这里是 demo