gpt4 book ai didi

c++ - boost::property_tree::json_parser 和两个字节宽的字符

转载 作者:可可西里 更新时间:2023-11-01 17:42:16 27 4
gpt4 key购买 nike

简介

std::string text = "á";

“á”是两个字节的字符(假设是 UTF-8 编码)。
所以下一行打印 2。

std::cout << text.size() << "\n";

std::cout 仍能正确打印文本。

std::cout << text << "\n";

我的问题

我将 text 传递给 boost::property_tree::ptree 然后传递给 write_json

boost::property_tree::ptree root;
root.put<std::string>("text", text);

std::stringstream ss;
boost::property_tree::json_parser::write_json(ss, root);
std::cout << ss.str() << "\n";

结果是

{
"text": "\u00C3\u00A1"
}

text 等于“á”,不同于“á”。

是否可以在不切换到 std::wstring 的情况下解决这个问题?是否有可能改变库 (boost::property_tree::ptree) 可以解决这个问题?

最佳答案

我找到了一些解决方案。通常,您需要为 [Ch=Char] 指定 boost::property_tree::json_parser::create_escapes 模板,以提供您的“特殊场合无错误转义”。

JSON 标准假设所有的字符串都是 UTF-16 编码的,使用“\uXXXX”转义,但是一些库支持使用“\xXX”转义的 UTF-8 编码。如果 JSON 文件可以用 UTF-8 编码,您可以传递所有高于 0x7F 的字符,这是为了原始功能。

我在使用 boost::property_tree::json_parser::write_json 之前放置了这段代码。它来自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;
}
} } }

我得到的输出:

{
"text": "aáb"
}

函数 boost::property_tree::json_parser::a_unicode 在将转义的 unicode 字符读取为有符号字符时也有类似的问题。

关于c++ - boost::property_tree::json_parser 和两个字节宽的字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10260688/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com