使用range-v3读取逗号分隔的数字列表 [英] Using range-v3 to read comma separated list of numbers

查看:176
本文介绍了使用range-v3读取逗号分隔的数字列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用Ranges(我使用range-v3实现)来读取输入流,该输入流是用逗号分隔的数字列表.在没有范围的情况下这样做是微不足道的,但是... 我认为这是解决问题的直接方法:

I'd like to use Ranges (I use range-v3 implementation) to read a input stream that is a comma separated list of numbers. That is trivial to do without ranges but... This is what I thought was the straight-forward way to solve it:

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

但这无法编译.我已经尝试了多种变体,但似乎无济于事,我猜这在几种方面都是错误的.有人可以告诉我我做错了什么,然后解释该怎么做吗?

But this fails to compile. I've tried a number of variations of this but nothing seem to work, I guess this is wrong in several ways. Can someone please enlighten me what I am doing wrong and explain how this should be done instead?

提前谢谢!

推荐答案

什么

ranges::istream_view<int>(input)

确实会产生一个与该协程大致相当的范围(即使您不了解C ++ 20协程,也希望此示例足够简单以至于可以理解这一点):

does is produce a range that is the rough equivalent of this coroutine (even if you don't understand C++20 coroutines, hopefully this example is simple enough that it gets the point across):

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的范围,因此不能在字符串上split对其进行split.
  2. 这使用普通流>>,不允许您提供自己的定界符-它仅在空白处停止.
  1. This is range of ints, so you cannot split it on a string.
  2. This uses the normal stream >>, which does not allow you to provide your own delimiter - it only stops at whitespace.

总的来说,istream_view<int>(input)为您提供范围为int的范围,该范围在您的输入中由单个int组成:仅42.下一个输入将尝试读取,并失败.

Altogether, istream_view<int>(input) gives you a range of ints that, on your input, consists of a single int: just 42. The next input would try to read in the , and fail.

为了获得定界输入,可以使用getlines.这将使您使用提供的定界符在string范围内.它在内部使用 std::getline .实际上,这就是协程:

In order to get a delimited input, you can use getlines. That will give you a range of string with the delimiter you provide. It uses std::getline internally. Effectively, it's this coroutine:

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

然后您需要将那些string转换为int.这样的事情应该可以解决问题:

And then you need to convert those strings to ints. Something like this should do the trick:

auto ints = ranges::getlines(input, ',')
          | ranges::view::transform([](std::string const& s){ return std::stoi(s); });

这篇关于使用range-v3读取逗号分隔的数字列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆