无法使用boost read_json读取变音符号

时间:2017-12-04 10:58:35

标签: c++ json boost encoding mfc

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

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。这部分不能改变。

1 个答案:

答案 0 :(得分:4)

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

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

以下是您如何转换字符串:

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&lt; - &gt; 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;
}