繁体   English   中英

使用 range-v3 读取逗号分隔的数字列表

[英]Using range-v3 to read comma separated list of numbers

我想使用 Ranges(我使用 range-v3 实现)来读取一个输入流,它是一个逗号分隔的数字列表。 如果没有范围,那是微不足道的,但是......这是我认为解决它的直接方法:

auto input = std::istringstream("42,314,11,0,14,-5,37");
auto ints = ranges::istream_view<int>(input) | ranges::view::split(",");
for (int i : ints)
{
    std::cout << i << std::endl;
}

但这无法编译。 我已经尝试了许多变体,但似乎没有任何效果,我想这在几个方面都是错误的。 有人可以请教我我做错了什么并解释应该如何做吗?

提前致谢!

什么

ranges::istream_view<int>(input)

do 是产生一个与这个协程大致等效的范围(即使你不理解 C++20 协程,希望这个例子足够简单,它可以理解这一点):

generator<int> istream_view_ints(istream& input) {
    int i;
    while (input >> i) {  // while we can still stream int's out
       co_yield i;        // ... yield the next int
    }
}

这里有两个重要的点:

  1. 这是int的范围,因此您不能splitsplit为字符串。
  2. 这使用普通流>> ,它不允许您提供自己的分隔符 - 它仅在空格处停止。

总而言之, istream_view<int>(input)为您提供了一系列int ,在您的输入中,该范围由单个int :仅42 下一个输入将尝试读入,并失败。


为了获得分隔的输入,您可以使用getlines 这将为您提供一系列带有您提供的分隔符的string 它在内部使用std::getline 实际上,它是这个协程:

generator<string> getlines(istream& input, char delim = '\n') {
    string s;
    while (std::getline(input, s, delim)) {
        co_yield s;
    }
}

然后你需要将这些string s 转换为int s。 像这样的事情应该可以解决问题:

auto ints = ranges::getlines(input, ',')
          | ranges::view::transform([](std::string const& s){ return std::stoi(s); });
std::string input = "42,314,11,0,14,-5,37";
auto split_view = ranges::view::split(input, ",");

将产生一系列范围:

{{'4', '2'}, {'3', '1', '4'}, {'1', '1'}, {'0'}, {'1', '4'}, {'-', '5'}, {'3', '7'}}

所以你可能会这样做:

std::string input = "42,314,11,0,14,-5,37";
auto split_view = ranges::view::split(input, ",");
for (auto chars : split_view) {
    for (auto c : chars) {
        std::cout << c;
    }
    std::cout << std::endl;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM