如何将C++输入流分隔符包含到结果令牌中?
如何将C++输入流分隔符包含到结果令牌中
嘿,这个需求很常见!默认情况下,C++输入流的分隔符(比如空格、你想用来分割的逗号)会被>>操作符直接跳过,不会出现在最终的令牌里。要把分隔符也纳入令牌,我们得调整输入流的字符分类规则,或者用更灵活的读取方式。你提到的自定义locale和ctype对象是个靠谱的方向,不过原代码里的逻辑有点问题,我来帮你修正并解释清楚:
方法一:自定义ctype特化,灵活控制分隔符处理
首先,原代码的do_is函数没有处理默认情况(即当字符既不是空格也不是逗号时,应该调用基类的do_is),而且把逗号标记为空白字符会导致它被跳过,这和我们的需求相反。我们需要根据实际需求调整字符分类:
场景1:把分隔符作为单独的令牌读取
比如输入a,b,c,希望得到"a"、","、"b"、","、"c"这类独立令牌,可以这样修改ctype特化:
#include <iostream> #include <locale> #include <string> struct csv_punct : std::ctype<char> { static const mask* make_table() { // 复制默认字符分类表 static std::vector<mask> table(classic_table(), classic_table() + table_size); // 确保逗号不属于空白字符(避免被跳过) table[','] &= ~space; // 将逗号标记为标点符号,让>>把它识别为单独令牌 table[','] |= punct; return table.data(); } csv_punct() : std::ctype<char>(make_table()) {} }; int main() { std::cin.imbue(std::locale(std::cin.getloc(), new csv_punct)); std::string token; while (std::cin >> token) { std::cout << "令牌:'" << token << "'\n"; } return 0; }
场景2:把分隔符和前置内容合并为一个令牌
比如输入a,b,c,希望得到"a,"、"b,"、"c"这类令牌,此时>>的默认逻辑不适用,我们可以写一个自定义提取函数:
#include <iostream> #include <string> // 自定义提取函数:读取到逗号时将其包含进当前令牌 std::istream& read_with_sep(std::istream& is, std::string& token) { token.clear(); char c; // 跳过前置空白(不需要的话可删除这段) while (is.get(c) && std::isspace(c)) {} if (!is) return is; token += c; // 读取直到遇到逗号或流结束,若遇到逗号则加入令牌 while (is.get(c)) { if (c == ',') { token += c; break; } token += c; } return is; } int main() { std::string token; while (read_with_sep(std::cin, token)) { std::cout << "令牌:'" << token << "'\n"; } return 0; }
方法二:用getline配合字符串流快速实现
如果场景比较简单,也可以先用std::getline读取整行,再通过字符串流拆分处理:
#include <iostream> #include <string> #include <sstream> int main() { std::string line; while (std::getline(std::cin, line)) { std::istringstream iss(line); std::string token; char sep; // 读取内容+分隔符,合并为一个令牌 while (iss >> token >> sep) { token += sep; std::cout << "令牌:'" << token << "'\n"; } // 处理最后一个无分隔符的令牌 if (!token.empty()) { std::cout << "令牌:'" << token << "'\n"; } } return 0; }
总结一下:自定义ctype是标准库推荐的灵活方案,适合复杂的字符分类需求;而自定义提取函数或getline组合字符串流,更适合简单场景,实现起来更直观。
内容的提问来源于stack exchange,提问作者amigo421
相关产品推荐
相关产品推荐

