C++中std::quoted怎么处理带引号字符串_C++文件流输入输出技巧【备忘】

3次阅读

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

C++中std::quoted怎么处理带引号字符串_C++文件流输入输出技巧【备忘】

std::quoted 会自动转义引号和空格,但只在流操作中生效

它不是字符串处理函数,而是专为 operatoroperator>> 设计的 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, '"', '') 关闭转义

std::quoted 不处理嵌套引号或 Unicode,也不保证 round-trip 安全

它只做简单线性解析:找第一个匹配分隔符,再往后扫描,遇到转义符就跳过下一个字符。这意味着:

  • 不支持 "" 表示一个 "(像 CSV 那样),只认 "
  • 遇到非 ASCII 字符(如中文引号“”)完全无感知
  • 若原始字符串结尾是转义符(如 "abc\" ),读取可能失败或抛 std::ios_base::failure
  • 写入后再读回,不一定等于原字符串——比如含控制字符 t 的字符串,std::quoted 不会转义它,但流输出时可能被当空白跳过

真要可靠序列化字符串,别依赖 std::quoted 做通用编码;它只是给简单配置场景省点事,边界情况得自己兜底。

text=ZqhQzanResources