繁体   English   中英

使用 range-v3 读取带有逗号分隔数据的行

[英]Using range-v3 to read lines with comma-separated data

是的,因为我最近问了一个非常相似的问题(如何读取逗号分隔的整数列表),但是这次我被困在读取由逗号分隔的数据组成的字符串行上。 将我之前处理整数的代码转换为处理数据块的字符串肯定很简单,对吧?

好的,所以我从一个文件或标准输入中读取数据,该文件或标准输入有很多行包含用逗号分隔的单词,例如:

hello,this,is,firstrow,sdf763  
this,is,2nd,row  
and,so,on314  

所以,我的想法只是使用ranges::getlines(或ranges::istream_view)从istream中读取数据行,将每一行通过管道传送到以逗号分割的拆分视图适配器以获得单词(作为范围的范围) ,然后我加入)并最终转换/解码每个单词,然后将其放入向量中。 恕我直言,它应该非常简单,就像:

std::string decode(const std::string& word);

int main()
{
    using namespace ranges;
    auto lines = getlines(std::cin);           // ["hello,this,is,firstrow,sdf763" "this,is,2nd,row" "and,so,on314" ...]
    auto words = lines | view::split(",");     // [["hello" "this" "is" "firstrow" "sdf763"] ["this" "is" "2nd" "row"] [...]]
    auto words_flattened = words | view::join; // ["hello" "this" "is" "firstrow" "sdf763" "this" "is" "2nd" "row" ...]
    auto decoded_words = words_flattened | view::transform([](const auto& word){
        return decode(word);
    }) | to_vector;

    for (auto word : decoded_words) {
        std::cout << word << "\n";
    }
    std::cout << std::endl;
}

但是不,这不起作用,我不知道为什么! 拆分视图适配器似乎根本不拆分行,因为整行作为参数传递给转换 - 为什么? 我显然仍在学习范围,但似乎仍然错过了一些基本概念......如果有人能解释发生了什么,我当然会很感激,提前致谢!

指向我之前的 SO 问题的链接: 使用 range-v3 读取逗号分隔的数字列表

拆分视图适配器似乎根本不拆分行,因为整行作为参数传递给转换 - 为什么?

因为这正是你不小心要求的。

split是一个适配器,需要一系列的T并产生一系列的范围T ,正对分隔符要么是由单一分割T或本身的范围内T秒。

当你写:

lines | views::split(",");

lines是一个字符串范围(不是单个字符串),并且您要求通过单个逗号的字符串分割该字符串范围 如果你有一系列的字符串,比如["A", ",", "B", "C", "D", ",", "E"] (即 7 个​​字符串,其中第二个和第六个是逗号)你会得到[["A"], ["B", "C", "D"], ["E"]]

但这不是你想要的。

你想要的是用逗号分割每个字符串。 那是:

lines | views::transform([](auto const& s) { return s | views::split(','); })

这需要您的RangeOf<string>并将其变成RangeOf<RangeOf<RangeOf<char>>> (这只会增加一层range -ness...因为stringRangeOf<char> 。但我们失去了string -ness )。

然后,您可以将它们join在一起:

lines | views::transform([](auto const& s) { return s | views::split(','); })
      | views::join;

现在我们回到RangeOf<RangeOf<char>> 如果我们真正想要的是RangeOf<string> ,我们需要将每个元素收集回一个:

lines | views::transform([](auto const& s) { return s | views::split(','); })
      | views::join
      | views::transform([](auto const& rc) { return rc | to<std::string>; });

或者,您可以将第二个变换移到第一个变换内部,以便在join之前收集到string s 中。

暂无
暂无

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

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