如何无需指定分隔符数量拆分std::istream并保留剩余输入?
解决方案:无需指定分隔符数量的字符串分割函数
先明确原函数的核心行为:
- 从输入流读取指定分隔符分割的片段,返回反转顺序的片段列表
- 最后一个分隔符之后的内容会留在输入流中,供后续操作调用
以下是修改后的实现,无需指定分隔符数量,自动处理所有分隔符:
#include <vector> #include <string> #include <istream> #include <algorithm> std::vector<std::string> separate_by_delimiter(std::istream &input, char delimiter) { std::vector<std::string> separated_list; std::string segment; std::streampos current_pos; while (true) { // 记录当前流位置,用于读取失败时回滚 current_pos = input.tellg(); if (!std::getline(input, segment, delimiter)) { // 读取失败,说明无更多分隔符 if (input.eof() && !segment.empty()) { // 若因流末尾导致失败且读取到内容,将这部分内容放回输入流 input.clear(); // 清除EOF状态 input.seekg(current_pos); // 回到读取前的位置 } break; } separated_list.push_back(segment); } // 反转列表,和原函数返回的顺序保持一致 std::reverse(separated_list.begin(), separated_list.end()); return separated_list; } // 使用示例 void outside_func(std::istream &input) { auto split_list = separate_by_delimiter(input, ','); int x; // 根据实际需求定义变量类型 input >> x; // 读取最后一个分隔符后的剩余内容 }
代码说明
- 流位置回滚:每次读取前记录流的当前位置,当
getline无法找到更多分隔符时,将流恢复到读取前的状态,确保最后一段内容留在输入流中供后续操作。 - 自动读取所有片段:循环读取所有由分隔符分割的片段,直到无法找到下一个分隔符为止。
- 顺序一致性:通过
std::reverse反转片段列表,和原函数用insert(separated_list.begin(), segment)实现的反转效果完全一致,且效率更高。
边界情况处理
- 输入流无分隔符:返回空列表,输入流内容完全保留,后续操作可读取全部内容。
- 输入流以分隔符结尾:会读取到一个空片段,最终列表包含所有有效片段的反转,流中无剩余内容。
- 流状态异常:若读取过程中出现非EOF的错误,直接终止循环,保留流的错误状态。
内容的提问来源于stack exchange,提问作者Pedi Alz
相关产品推荐
相关产品推荐

