使用ranges::to<std::vector>时CSV数据重复乱码问题
C++ Ranges管道添加ranges::tostd::vector后CSV最后一行重复乱码的解决方案
使用C++ Ranges库读取CSV文件时,直接遍历处理输出正常,但在管道末尾添加ranges::to<std::vector>后,输出的最后一行出现重复且乱码的情况。
正确输出示例:
"Values to Analyze, Current", 1, 7, 2025, 5, 218, 11, 23, 119 "Values to Analyse, Current", 1, 8, 2025, 21, 2055, 1, 7, 131 "Values to Analyse, Current", 1, 9, 2025, 29, 210, 3, 4, 105 "Values to Analyse, Current", 1, 10, 2025, 5, 214, 4, 7, 124
乱码输出示例:
"Values to Analyse, Current", 1, 10 ,2025 ,5 ,214 ,4, 7,1 24 "Values to Analyse, Current", 1, 10 ,2025 ,5, 214,4 ,7 ,1 24 "Values to Analyse, Current", 1, 10 ,2025 ,5, 214, 4, 7, 124 "Values to Analyse, Current", 1, 10, 2025, 5, 214, 4, 7, 124
问题根源
问题的核心是parse_csv转换逻辑中使用了静态变量static bool is_quoting,这个变量会在所有行的处理过程中共享状态。Ranges的视图是延迟计算的,当使用ranges::to<std::vector>触发完整迭代时,静态变量的状态会在不同行的处理间意外保留,导致CSV的引号分割逻辑混乱,最终出现重复乱码的输出。
具体来说,is_quoting用于标记当前是否处于引号范围内,原本应该每行处理前重置为false,但静态变量的特性导致它会保留上一行处理后的状态,破坏了每行独立的解析逻辑。
修复方案
将静态变量is_quoting改为每行处理时的局部变量,确保每行的引号状态独立,不会互相干扰。修改后的parse_csv代码如下:
auto parse_csv = transform([](auto&& line) { // bool is_quoting{false}; // 移除static,改为局部变量 return line.mLine // | chunk_by([&is_quoting](char const lhs, char const) { if (lhs == '"') { is_quoting = !is_quoting; } return (lhs != ',' or is_quoting); }) // | to_vec; });
修改后,每行解析时都会初始化独立的is_quoting变量,引号状态不会跨行传递,无论是直接遍历视图还是转换为std::vector后遍历,都能得到正确的输出。
内容的提问来源于stack exchange,提问作者Rud48
相关产品推荐
相关产品推荐

