【问题标题】:Can not read umlauts with boost read_json无法使用 boost read_json 读取变音符号
【发布时间】:2017-12-04 10:58:34
【问题描述】:

我无法用 boost::property_tree::read_json 解决我的问题。我有 MBCS 编码(多字节字符集)的 MFC 项目。在使用 ä 字符读取数据时出现错误。这是我的例子:

namespace pt = boost::property_tree;

pt::ptree rootRequest;

//Save data in property tree
rootRequest.put("test", "Test ä");

//create stringstream
std::stringstream ss;

//Write rootRequest to stringstream
try
{
    pt::write_json(ss, rootRequest);
}
catch (std::exception const &e)
{
    TRACE("Error: [%s]\n", e.what());
}

//Get string from stringstream
std::string strRequest = ss.str();
TRACE("data: [%s]\n", CString(strRequest.c_str()));

//Clear stringstream
ss.str(std::string());

//Sate data to stringstream
ss << strRequest;

//Save string data in ptree value
pt::ptree rootResponse;
try
{
    pt::read_json(ss, rootResponse);   //Here I'm getting error

}
catch (std::exception const &e)
{
    TRACE("Error: [%s]\n", e.what());
}

我收到以下异常:

<unspecified file>(2): invalid code sequence

读取此类数据的正确方法是什么?我希望有人可以帮助我解决这个问题。我需要将数据保存在string 中,然后再将其读到stringstream。此部分无法更改。

【问题讨论】:

  • 不要使用 MBCS 编码。将 UNICODE 用于新项目,自从 MS 将 Windows 的原生字符串格式更改为 UNICODE 以来,MBCS 已经死了。
  • 我不能。我有维护项目,无法更改编码。
  • JSON 无法处理原始 MBCS,您必须将所有字符串转换为 UTF-8。

标签: c++ json boost encoding mfc


【解决方案1】:

JSON 不能存储 MBCS 字符串。这意味着必须在保存之前将所有标签和值转换为 UTF-8 或 UTF-16。

UTF-8 是 JSON 的常用选择,不仅因为它使用较少的字符串内存,还因为 UTF-8 编码具有 1 对 1 的唯一字形编码,而 UTF-16 没有。

以下是转换字符串的方法:

MBCS 到 Unicode:

#include <windows.h>
#include <string>

std::wstring MBCS_to_UTF16(LPCSTR sz)
{
    // MBCS to UNICODE
    std::wstring strResult;

    size_t nCharsDone = 0;
    const size_t nMaxsWords = 6 * strlen(sz);

    strResult.resize(nMaxsWords + 1);

    if (S_OK == ::mbstowcs_s(&nCharsDone, &strResult[0], nMaxsWords + 1, sz, nMaxsWords))
        strResult.resize(nCharsDone);
    else
        strResult.clear();
    return strResult;
}

UTF16 UTF8:

#include <boost/locale.hpp>

std::string strUTF8 = boost::locale::conv::utf_to_utf<char>(L"hello"); // 
std::wstring strUTF16 = boost::locale::conv::utf_to_utf<wchar_t>("hello");

UTF16 转 MBCS:

std::string UTF16_to_MBCS(LPCWSTR wsz)
{
    // MBCS to UNICODE
    std::string strResult;

    size_t nCharsDone = 0;
    const size_t nMaxWords = 2 * wcslen(wsz);

    strResult.resize(nMaxWords + 1);

    if (S_OK == ::wcstombs_s(&nCharsDone, &strResult[0], nMaxWords + 1, wsz, nMaxWords))
        strResult.resize(nCharsDone);
    else
        strResult.clear();
    return strResult;
}

【讨论】:

  • 从 C++11 开始,可以简化 MBCS 转换,对于 MBCS -> UTF-16:std::wstring_convert&lt;std::codecvt&lt;wchar_t, char, std::mbstate_t&gt;&gt; conv; std::wstring outputUtf16 = conv.from_bytes( inputMBCS );,对于 UTF-16 -> MBCS:std::string outputMBCS = conv.to_bytes( inputUTF16 );。要处理转换错误,请捕获 std::range_error
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多