2015-11-03 c++ builder XE4 / JSON > "\"付きの文字列の扱いに失敗する > "\\"ではなく"\\\\"にする


動作確認
C++ Builder XE4

JSON文字列の扱いにて、Size()の処理が失敗する。

症状

#include <DBXJSON.hpp>
#include <memory>

...
void __fastcall TForm1::Button1Click(TObject *Sender)
{

    // Case 1: OK
//  String jsonText = L"{\"name\":\"John Smith\",\"age\":\"33\"}";

    // Case 2: NG
    String jsonText = L"{\"name\":\"C:\\Windows\",\"age\":\"33\"}";

    std::unique_ptr<TStringList> slread(new TStringList);

    TJSONObject *jsonObj = new TJSONObject();
    String jsonKey, jsonValue;
    TJSONPair *pairObj;

    jsonObj = dynamic_cast<TJSONObject*>(TJSONObject::ParseJSONValue(jsonText));

    for(int pi=0; pi < jsonObj->Size(); pi++) { // pair index
        pairObj = jsonObj->Get(pi);
        jsonKey = pairObj->JsonString->Value();
        jsonValue = pairObj->JsonValue->Value();
        ShowMessage(jsonKey + ":" + jsonValue);
    }
    jsonObj->Free();
}

Case1ではOKでCase2では失敗する。

評価/変更ウィンドウでjsonObj->Size()を評価しようとすると以下のエラーが出る。

E2122 関数呼び出しが未処理例外 '0xc0000005'によってアドレス'0x91dd50'で終了した。

デバッガで停止しない場合は以下のエラーメッセージが表示される。

モジュール'DbxCommonDriver180.bpl'のアドレス 521FB4DCでアドレス 000000008に対する読り違反がおきました。

"\"の扱いがダメなのだろう。
置換で対応するかどうか。

try1 (成功)

String jsonText = L"{\"name\":\"C:\\Windows\",\"age\":\"33\"}";

String jsonText = L"{\"name\":\"C:\\\\Windows\",\"age\":\"33\"}";
にしたらエラーが出なくなった。

置換は

jsonText = StringReplace(jsonText, L"\\", L"\\\\", TReplaceFlags()<<rfReplaceAll);

JSONファイル保存時でなく、JSONファイル読込時に上記の置換をすることにより、うまく動作した。