c++ - 使用 range-v3 读取逗号分隔数据的行
问题描述
再次是的,因为我最近问了一个非常相似的问题(如何读取逗号分隔的整数列表),但是这次我被困在读取由逗号分隔的数据组成的字符串行上。将我之前处理整数的代码转换为处理数据块字符串肯定很简单,对吧?
好的,所以我从一个文件或标准输入中读取数据,该文件或标准输入有很多行,其中包含用逗号分隔的单词,例如:
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;
}
但是不,这不起作用,我不知道为什么!拆分视图适配器似乎根本没有拆分行,因为整行作为参数传递给 transform - 为什么会这样?我显然仍在学习范围,并且似乎仍然错过了一些基本概念......如果有人能解释发生了什么,我当然会很感激,在此先感谢!
我之前的 SO 问题的链接:使用 range-v3 读取逗号分隔的数字列表
解决方案
拆分视图适配器似乎根本没有拆分行,因为整行作为参数传递给 transform - 为什么会这样?
因为这正是你不小心要求的。
split
是一个适配器,它接受一个范围T
并产生一个范围的范围T
,在一个分隔符上进行拆分,该分隔符要么是单个的,T
要么本身就是一个T
s 的范围。
当你写:
lines | views::split(",");
lines
是一个字符串范围(不是单个字符串),并且您要求将该字符串范围划分为单个逗号的字符串。如果你有一系列字符串["A", ",", "B", "C", "D", ",", "E"]
(即 7 个字符串,其中第 2 个和第 6 个是逗号),你会得到 back [["A"], ["B", "C", "D"], ["E"]]
。
但这不是你想要的。
你想要的是用逗号分割每个字符串。那是:
lines | views::transform([](auto const& s) { return s | views::split(','); })
这需要你RangeOf<string>
并将其变成 a RangeOf<RangeOf<RangeOf<char>>>
(这只增加了一层range
-ness... 因为string
是 a RangeOf<char>
。但我们失去了string
-ness )。
然后,您可以将join
它们放在一起:
lines | views::transform([](auto const& s) { return s | views::split(','); })
| views::join;
现在我们回到RangeOf<RangeOf<char>>
. 如果我们真正想要的是 a RangeOf<string>
,我们需要将每个元素收集回一个:
lines | views::transform([](auto const& s) { return s | views::split(','); })
| views::join
| views::transform([](auto const& rc) { return rc | to<std::string>; });
或者,您可以将第二个变换移动到第一个变换中,以便在您string
之前收集到 s 中join
。
推荐阅读
- angular - ng2-file-upload 的内部 express 服务器返回 500 错误
- vue.js - 如何检索元素ID vue js
- async-await - 有没有办法等到函数完成?
- regex - 在文本中查找钱的正则表达式
- kubernetes-helm - 使用全局变量时,helm 子图是否依赖于父图?
- angular - 如何使用 *ngFor 编写条件来检查两个值
- json - 我应该如何在 NewtonSoft.Json 序列化的 JSON 配置文件中实现环境变量替换
- asp.net - ASP.NET TargetSchema 用户控制指令
- c - 查找数组中两个数字的目标总和
- macos - ubuntu 和 OSX 上 xattr.h 中函数定义的差异