14244


C++でJSONをパースするのに、PicoJSONを使っているのですが、次のJSONファイルがどうしても読み込めません。エラーの原因と、解決方法を教えていただけないでしょうか。main.cppの2つ目のfor文内のコメントを取り払うと、エラーメッセージが出ます。

test.json

[code]

    {"glossary":
        [
            {"title_list":
                [
                    {"title": "SGML","primary": 1},
                    {"title": "GlossDef","primary": 0},
                    {"title": "Abbrev","primary": 3}
                ]
            ,"binding":
                {"design": 1, "page": 1000}
            }
        ]
    }
    
[/code]

main.cpp

[code]

    #include <sstream>
    #include <fstream>
    #include <iostream>
    #include <picojson.h>
    
    using namespace std;
    using namespace picojson;
    
    int main(void) {
    //Declartion
    stringstream ss;
    ifstream f;
    
    //Read Json file
    f.open("test.json", ios::binary);
    if(!f.is_open()) {
        return 1;
    }
    ss << f.rdbuf();
    f.close();
    
    //Parse Json data
    picojson::value val;
    ss >> val;
    string err = get_last_error();
    if(!err.empty()) {
        cerr << err << endl;
        return -1;
    }
    
    object& obj = val.get<object>();
    
    array& glossary = obj["glossary"].get<array>();
    cout << "glossary: " << endl;
    for (array::iterator it = glossary.begin(); it != glossary.end(); it++) {
        //title_list
        object& tmp = it->get<object>();
        array& title_list = tmp["title_list"].get<array>();
        for (array::iterator it2 = title_list.begin(); it2 != title_list.end(); it2++) {
            object& title_list = it2->get<object>();
            object& title = title_list["title_list"].get<object>();
            //object& primary = title_list["title_list"].get<object>();
            //cout << "\ttitle: " << title["title"].get<string>();
            //cout << ", primary: " << primary["primary"].get<double>() << endl;
        }
    
        //binding
        object& binding = it->get<object>();
        object& design = binding["binding"].get<object>();
        object& page = binding["binding"].get<object>();
        cout << "binding: " << endl;
        cout << "\tdesign: " << design["design"].get<double>();
        cout << ", binding: " << page["page"].get<double>() << endl;
        }
    
    return 0;
    }
    
[/code]

error message

[code]

    terminate called after throwing an instance of 'std::runtime_error'
    what():  "type mismatch! call is<type>() before get<type>()" && is<object>()
    Aborted (core dumped)
    
[/code]

PicoJSONの公式ページを参考にしつつ、色々試してみたのですが、解決出来ませんでした。基本的な質問かもしれませんが、よろしくお願いします。


CC BY-SA 3.0
2015-08-10T13:33:49.950
14240
2015-08-10T14:56:11.640
10866
question
c++ json
PicoJSONでarray型の読み込み


対象の JSON ファイルの構造を考えますと、以下の処理において、`title` に `NULL`
が代入されてしまう事になります(`"title_list"` キーがありませんので…)。

[code]

    object& title = title_list["title_list"].get<object>();
    
[/code]

`get<object>()` を実行する前に以下を実行すると分かるかと思います。

[code]

    if ( title_list["title_list"].is<null>() ) {
      cout << "NULL" << endl;
    }
    
[/code]

ですので、以下の様にすれば良いかと思います。

[code]

    for (array::iterator it = glossary.begin(); it != glossary.end(); it++) {
      //title_list
      object& tmp = it->get<object>();
      array& title_list = tmp["title_list"].get<array>();
      for (array::iterator it2 = title_list.begin(); it2 != title_list.end(); it2++) {
          object& title = it2->get<object>();
          cout << "\ttitle: " << title["title"].get<string>();
          cout << ", primary: " << title["primary"].get<double>() << endl;
      }
    
      //binding
      object& design = tmp["binding"].get<object>();
      cout << "binding: " << endl;
      cout << "\tdesign: " << design["design"].get<double>();
      cout << ", binding: " << design["page"].get<double>() << endl;
    }
    
[/code]


CC BY-SA 3.0
2015-08-10T14:56:11.640
14244
2015-08-10T14:56:11.640
14240
answer