boost::property_tree写JSON时受区域设置影响出现非预期数字格式问题求助
boost::property_tree 写入JSON时数字带千位分隔符问题解决方案
这个是boost::property_tree的JSON序列化模块的典型适配问题,已有大量开发者遇到过同类场景。
问题根因
boost::property_tree的json_parser序列化逻辑默认会继承当前运行环境的全局区域设置:
- 字符编码输出依赖区域设置的
codecvtfacet,这也是需要保留fr_FR.UTF-8全局配置来正常输出éàè等特殊字符的原因 - 数字格式化逻辑依赖区域设置的
numpunctfacet,不同区域的千位分隔符规则不同,就会出现英文环境加逗号、法语环境加空格的非预期行为
两个facet互相独立,不需要绑定使用,因此可以通过自定义区域配置解决冲突。
可行解决方案
保留原有全局区域设置保证字符编码正常,仅在JSON输出的流层面单独覆盖数字格式化规则即可,不会影响其他业务逻辑对全局区域配置的依赖。
实现代码如下:
// 原有全局配置保留,保证全链路UTF-8字符处理正常 std::locale::global(std::locale("fr_FR.UTF-8")); // JSON写入逻辑单独配置区域规则 #include <boost/property_tree/json_parser.hpp> #include <fstream> #include <locale> void write_standard_json(const std::string& file_path, const boost::property_tree::ptree& pt) { std::ofstream output_stream(file_path); // 构造自定义区域:继承全局区域的所有配置,仅替换数字格式化规则为C标准无千位分隔符模式 std::locale json_locale(std::locale(), new std::numpunct<char>()); output_stream.imbue(json_locale); // 序列化输出JSON,此时数字不会带千位分隔符,特殊字符也能正常写入 boost::property_tree::write_json(output_stream, pt); }
方案说明
- 自定义的
json_locale仅作用于当前JSON输出流,不会修改全局区域配置,对其他业务逻辑无侵入 - 内置的
std::numpunct<char>默认没有千位分隔符,完全符合JSON标准的数字格式要求 - 保留了原全局区域的编码转换能力,éàè等UTF-8特殊字符可以正常输出
内容的提问来源于stack exchange,提问作者Gregoire
相关产品推荐
相关产品推荐

