[英]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...因为string
是RangeOf<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.