2017-12-04 27 views
1

boost :: property_tree :: read_jsonで問題を解決できません。 MBCSエンコーディング(マルチバイト文字セット)のMFCプロジェクトがあります。 ä文字でデータを読み取っているときにエラーが発生します。これは私の例である:ブーストread_jsonでウムラウトを読み取れません

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に読み込む必要があります。この部分は変更できません。

+0

MBCSエンコードを使用しないでください。新しいプロジェクトにUNICODEを使用すると、MBCSはWindowsのネイティブ文字列形式をUNICODEに変更して以来MBCSは死亡しています。 –

+0

できません。メンテナンスプロジェクトがあり、エンコーディングは変更できません。 – drewpol

+1

JSONは生のMBCSを処理できません。すべての文字列をUTF-8に変換する必要があります。 –

答えて

4

JSONはMBCS文字列を格納できません。つまり、保存する前に、すべてのラベルと値をUTF-8またはUTF-16に変換する必要があります。

UTF-8はJSONの通常の選択です。文字列のメモリが少ないだけでなく、UTF-8エンコーディングには1対1のユニークなグリフエンコーディング(UTF-16ではないため)があるためです。 Unicodeに

MBCS:ここ

はあなたの文字列を変換したい方法です

#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; 
} 
+4

C++ 11以降では、MBCS - > UTF-16の場合、MBCS変換を簡略化できます: 'std :: wstring_convert > conv; std :: wstring outputUtf16 = conv.from_bytes(inputMBCS);およびUTF-16の場合 - > MBCS: 'std :: string outputMBCS = conv.to_bytes(inputUTF16);'。変換エラーを処理するには 'std :: range_error'をキャッチします。 – zett42

+0

クールなチップ、ありがとう@ zett42! –

関連する問題