首页 新闻 搜索 专区 学院

在c++里boost:ptree 用作生成json,中文乱码如何解决?

0
悬赏园豆:100 [已关闭问题] 关闭于 2014-11-14 13:52

使用boost/property_tree/ptree和boost/property_tree/json_parser进行json串生成,write_json()遇到中文时会成乱码,改如何解决?

  

qwer075的主页 qwer075 | 初学一级 | 园豆:127
提问于:2014-11-13 10:55
< >
分享
所有回答(2)
0

在stack OverFlow 找到答案,贴过来:

I found some solutions. In general you needs to specify boost::property_tree::json_parser::create_escapes template for [Ch=Char], to provide your "special occasion bug free escaping".

JSON standard assume that all string are UTF-16 encoded with "\uXXXX" escaping, but some library support UTF-8 encoding with "\xXX" escaping. If JSON file can be encoded in UTF-8, you may pass all character higher than 0x7F, witch was intended for original function.

I put this code before using boost::property_tree::json_parser::write_json. It comes from boost_1_49_0/boost/property_tree/detail/json_parser_write.hpp:

namespace boost { namespace property_tree { namespace json_parser
{
    // Create necessary escape sequences from illegal characters
    template<>
    std::basic_string<char> create_escapes(const std::basic_string<char> &s)
    {
        std::basic_string<char> result;
        std::basic_string<char>::const_iterator b = s.begin();
        std::basic_string<char>::const_iterator e = s.end();
        while (b != e)
        {
            // This assumes an ASCII superset. But so does everything in PTree.
            // We escape everything outside ASCII, because this code can't
            // handle high unicode characters.
            if (*b == 0x20 || *b == 0x21 || (*b >= 0x23 && *b <= 0x2E) ||
                (*b >= 0x30 && *b <= 0x5B) || (*b >= 0x5D && *b <= 0xFF)  //it fails here because char are signed
                || (*b >= -0x80 && *b < 0 ) ) // this will pass UTF-8 signed chars
                result += *b;
            else if (*b == char('\b')) result += char('\\'), result += char('b');
            else if (*b == char('\f')) result += char('\\'), result += char('f');
            else if (*b == char('\n')) result += char('\\'), result += char('n');
            else if (*b == char('\r')) result += char('\\'), result += char('r');
            else if (*b == char('/')) result += char('\\'), result += char('/');
            else if (*b == char('"'))  result += char('\\'), result += char('"');
            else if (*b == char('\\')) result += char('\\'), result += char('\\');
            else
            {
                const char *hexdigits = "0123456789ABCDEF";
                typedef make_unsigned<char>::type UCh;
                unsigned long u = (std::min)(static_cast<unsigned long>(
                                                 static_cast<UCh>(*b)),
                                             0xFFFFul);
                int d1 = u / 4096; u -= d1 * 4096;
                int d2 = u / 256; u -= d2 * 256;
                int d3 = u / 16; u -= d3 * 16;
                int d4 = u;
                result += char('\\'); result += char('u');
                result += char(hexdigits[d1]); result += char(hexdigits[d2]);
                result += char(hexdigits[d3]); result += char(hexdigits[d4]);
            }
            ++b;
        }
        return result;
    }
} } }
qwer075 | 园豆:127 (初学一级) | 2014-11-14 13:51
0

我也遇到同样问题,问题解决了。

世界的意识 | 园豆:202 (菜鸟二级) | 2015-08-27 16:41

QQ504112619,如果楼主还没解决可以Q我

支持(0) 反对(0) 世界的意识 | 园豆:202 (菜鸟二级) | 2015-08-27 16:42

@世界的意识: windows端用 wptree可解决,但是linux端解决方案不可行。你是咋解决的呢?谢谢

支持(0) 反对(0) 林毅0801 | 园豆:200 (初学一级) | 2017-11-03 10:15
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册