std::quoted是专为流操作设计的I/O操纵器,不修改字符串本身,仅在读写时自动处理引号与转义;默认用"和\,支持自定义分隔符与转义符,但不支持嵌套引号、Unicode及通用序列化。

std::quoted 会自动转义引号和空格,但只在流操作中生效
它不是字符串处理函数,而是专为 operator 和 operator>> 设计的 I/O 操纵器。直接对 std::string 调用 std::quoted 不会修改内容,只是包装成一个临时对象,等待流读写时触发转义逻辑。
常见错误是以为 std::quoted(str) 会返回带引号+转义的新字符串——实际不会。它返回的是 std::quoted_manip 类型,必须配合流使用:
std::ostringstream oss;
oss << std::quoted("a b\"c");
// 输出: "a b\"c"
如果想拿到处理后的字符串,得手动构造:"\"" + str + "\"" 或用 std::regex_replace 处理内部引号,但那已脱离 std::quoted 的本意。
文件流读取带引号字段时,std::quoted 能跳过外层引号并还原转义
适用于 CSV 或配置文件中用双引号包裹、内部含空格/制表符/引号的字段。例如文件内容为:
立即学习“C++免费学习笔记(深入)”;
"hello world" 42 "she said \"yes\""
用 std::quoted 可安全提取:
std::ifstream ifs("config.txt");
std::string s1, s3;
int i;
ifs >> std::quoted(s1) >> i >> std::quoted(s3);
// s1 == "hello world", s3 == "she said \"yes\""
- 自动剥离首尾引号
- 把
\"还原为",\\还原为\ - 不支持单引号包裹,也不识别其他转义(如
\n) - 若字段没引号,
std::quoted仍按普通字段读取(但不会加引号)
std::quoted 的 delimiter 和 escape 参数容易被忽略
默认用 " 作分隔符、\ 作转义符,但可自定义:
std::string s = "a|b|c";
std::istringstream iss("|" + s + "|");
std::string out;
iss >> std::quoted(out, '|', '~'); // 分隔符'|',转义符'~'
// out == "a|b|c"
- 第二个参数是分隔符(char),第三个是转义符(char)
- 若源字符串里有未转义的分隔符(如
"a|b"且分隔符是|),读取会失败或截断 - Windows 路径中常见
\冲突:若用默认转义符,"C:\\temp"会被误认为转义序列;此时建议改用std::quoted(s, '"', '\0')关闭转义
std::quoted 不处理嵌套引号或 Unicode,也不保证 round-trip 安全
它只做简单线性解析:找第一个匹配分隔符,再往后扫描,遇到转义符就跳过下一个字符。这意味着:
- 不支持
""表示一个"(像 CSV 那样),只认\" - 遇到非 ASCII 字符(如中文引号“”)完全无感知
- 若原始字符串结尾是转义符(如
"abc\\"),读取可能失败或抛std::ios_base::failure - 写入后再读回,不一定等于原字符串——比如含控制字符
\t的字符串,std::quoted不会转义它,但流输出时可能被当空白跳过
真要可靠序列化字符串,别依赖 std::quoted 做通用编码;它只是给简单配置场景省点事,边界情况得自己兜底。










