最近Linux生产环境在用boost库生成json的时候发现中文乱码,经调测发现是boost库的bug,在此记录。
boost生成Json
一般用法
boost有两个数据结构,其中一个是 property::ptree
, 这个数据结构可以表示 xml
json
ini
等格式的文件内容,在不使用第三方比如 jsonpp
等库的情况下,在使用boost的情况下也不需要引入其他库,一般操作完 ptree
之后按 json
格式输出就行。
boost::property_tree::ptree pt; |
但是在使用低版本的时候(我使用的是1.53版本),偶然使用到中文的时候,输出内容竟然是 \uxxxx
这样的编码,但事实上输入的中文确实是要求的UTF-8编码,有些人说使用 wptree
,但我们并没有使用宽字符,而且由于本地调试的时候没有问题(本地版本较高),最终发现是该库的一个BUG。
原因分析
具体来说,在文件 boost/property_tree/json_parser/detail/write.hpp
中的 create_escapes
函数中,在低版本的实现中(具体是哪个版本修复的没有去追查),在编码的时候大概是下面的代码
if (*b == 0x20 || *b == 0x21 || (*b >= 0x23 && *b <= 0x2E) || |
这个代码的意思是判断是否需要编码的逻辑,其中 *b
其实就是 char
,特别需要主要的是比较是不成立的。
为什么!
如果你了解UTF8字符集大概就明白了,字符集编码范围,举例说明,中文 你
的编码是 0xe4 0xbd 0xa0
咋一看好像是符合上面的条件,但是注意 char
的范围,因此这几个字节值以 char
类型表示的时候就变成了负数了,上面的条件是不成立的。
知道了为什么,改起来就很方便了,包括其后续的版本的修复也是一样的
typedef typename make_unsigned<Ch>::type UCh; |
当然也可以升级高版本解决。