Search code examples
c++jsonjsoncpp

Parsing JSON string with jsoncpp


I'm trying to parse a JSON string encoded with PHP and sent over TCP to a C++ client.

My JSON strings are like this:

{"1":{"name":"MIKE","surname":"TAYLOR"},"2":{"name":"TOM","surname":"JERRY"}}

On the C++ client I'm using the jsoncpp libraries:

void decode()
{
    string text =     {"1":{"name":"MIKE","surname":"TAYLOR"},"2":{"name":"TOM","surname":"JERRY"}};
    Json::Value root;
    Json::Reader reader;
    bool parsingSuccessful = reader.parse( text, root );
    if ( !parsingSuccessful )
    {
        cout << "Error parsing the string" << endl;
    }
    const Json::Value mynames = root["name"];
    for ( int index = 0; index < mynames.size(); ++index )  
    {
        cout << mynames[index] << endl;
    }
}

The problem is that I'm not getting anything as output, not even the error about the parsing(if any). Could you possibly help me to understand what I'm doing wrong ?


Solution

  • Your problem is: there is no root["name"]. Your document should be like this:

    { "people": [{"id": 1, "name":"MIKE","surname":"TAYLOR"}, {"id": 2, "name":"TOM","surname":"JERRY"} ]}
    

    And your code like this:

    void decode()
    {
        string text ="{ \"people\": [{\"id\": 1, \"name\":\"MIKE\",\"surname\":\"TAYLOR\"}, {\"id\": 2, \"name\":\"TOM\",\"surname\":\"JERRY\"} ]}";
        Json::Value root;
        Json::Reader reader;
        bool parsingSuccessful = reader.parse( text, root );
        if ( !parsingSuccessful )
        {
            cout << "Error parsing the string" << endl;
        }
    
        const Json::Value mynames = root["people"];
    
        for ( int index = 0; index < mynames.size(); ++index )
        {
            cout << mynames[index] << endl;
        }
    }
    

    If you want to keep your data as is:

    void decode()
    {
      //string text ="{ \"people\": [{\"id\": 1, \"name\":\"MIKE\",\"surname\":\"TAYLOR\"}, {\"id\": 2, \"name\":\"TOM\",\"surname\":\"JERRY\"} ]}";
      string text ="{ \"1\": {\"name\":\"MIKE\",\"surname\":\"TAYLOR\"}, \"2\": {\"name\":\"TOM\",\"surname\":\"JERRY\"} }";
      Json::Value root;
      Json::Reader reader;
      bool parsingSuccessful = reader.parse( text, root );
      if ( !parsingSuccessful )
      {
        cout << "Error parsing the string" << endl;
      }
    
      for( Json::Value::const_iterator outer = root.begin() ; outer != root.end() ; outer++ )
      {
        for( Json::Value::const_iterator inner = (*outer).begin() ; inner!= (*outer).end() ; inner++ )
        {
          cout << inner.key() << ": " << *inner << endl;
        }
      }
    }
    

    Traverse the root object directly, using iterators (don't treat it as it was an array.

    If Json::Reader doesn't work, try Json::CharReader instead:

    void decode()
    {
      string text ="{\"1\":{\"name\":\"MIKE\",\"surname\":\"TAYLOR\"},\"2\":{\"name\":\"TOM\",\"surname\":\"JERRY\"}}";
    
      Json::CharReaderBuilder builder;
      Json::CharReader * reader = builder.newCharReader();
    
      Json::Value root;
      string errors;
    
      bool parsingSuccessful = reader->parse(text.c_str(), text.c_str() + text.size(), &root, &errors);
      delete reader;
    
      if ( !parsingSuccessful )
      {
        cout << text << endl;
        cout << errors << endl;
      }
    
      for( Json::Value::const_iterator outer = root.begin() ; outer != root.end() ; outer++ )
      {
        for( Json::Value::const_iterator inner = (*outer).begin() ; inner!= (*outer).end() ; inner++ )
        {
          cout << inner.key() << ": " << *inner << endl;
        }
      }
    }