【问题标题】:Taking n lines from a file which contains m lines, repeating the file (lazily) if necessary从包含 m 行的文件中取出 n 行,必要时重复该文件(懒惰地)
【发布时间】:2020-11-04 06:47:21
【问题描述】:

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

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

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

这是一个示例输入文件,

line 1
line 2
line 3

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

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

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

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

【问题讨论】:

  • 不太清楚你到底要什么。但是您可以使用std::ifstreamstd::getline() 循环读取整行的文本文件,直到您想停止读取行。
  • @RemyLebeau,现在清楚了吗?

标签: c++ boost functional-programming lazy-evaluation boost-hana


【解决方案1】:

要在 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;
}

【讨论】:

  • 这种方法不会重复重新分配result吗?
  • std::string 有一个 capacity 以块的形式增长,因此它不需要在每个单独的追加时重新分配内存。如果您知道需要多少内存(例如,在您的示例中,6 * nLines),您也可以提前reserve() 字符串的内存以减少重新分配。
  • seekg() 是否真的从 eof 重置了流错误状态?
  • @sehe in C++11 and later, yes: "在做任何事情之前, seekg 清除 eofbit。(C++11 起)"
【解决方案2】:

假设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

【讨论】:

  • 你抢了我的风头。这至少是 Haskell 程序员所期望的。
  • 呜呜呜呜。
猜你喜欢
  • 2012-08-13
  • 1970-01-01
  • 1970-01-01
  • 2016-02-19
  • 1970-01-01
  • 1970-01-01
  • 2019-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多