Monday, June 6, 2011

Using JsonCpp to parse JSON in C++

We are using JSON (JavaScript Object Notation) to write the configuration files for our simulations.

JSON is a lightweight data-interchange format. The good thing is that JSON is easy for humans to read and write and that you can find good C++ libraries that parse and write it.

We're using one of them: JsonCpp.

There were several other C++ libraries listed in the JSON project website, but JsonCpp's documentation convinced me to use it.

I installed JsonCpp as a shared library (I'll soon post here how to do it in Linux and MacOs) and wrote a tiny example to test it:

#include <cstdio>
#include <cstring>

// This is the JSON header
#include "jsoncpp/json.h"

using namespace std;

int main(int argc, char **argv)
{
 string json_example = "{\"array\": \
                            [\"item1\", \
                            \"item2\"], \
                            \"not an array\": \
                            \"asdf\" \
                         }";

 // Let's parse it  
 Json::Value root;
 Json::Reader reader;
 bool parsedSuccess = reader.parse(json_example, 
                                   root, 
                                   false);
  
 if(not parsedSuccess)
 {
   // Report failures and their locations 
   // in the document.
   cout<<"Failed to parse JSON"<<endl 
       <<reader.getFormatedErrorMessages()
       <<endl;
   return 1;
 }
  
 // Let's extract the array contained 
 // in the root object
 const Json::Value array = root["array"];
 
 // Iterate over sequence elements and 
 // print its values
 for(unsigned int index=0; index<array.size(); 
     ++index)  
 {  
   cout<<"Element " 
       <<index 
       <<" in array: "
       <<array[index].asString()
       <<endl;
 }
  
 // Lets extract the not array element 
 // contained in the root object and 
 // print its value
 const Json::Value notAnArray = 
               root["not an array"];
 
 if(not notAnArray.isNull())
 {
   cout<<"Not an array: "
       <<notAnArray.asString()
       <<endl;
 }
 
 // If we want to print JSON is as easy as doing:
 cout<<"Json Example pretty print: "
     <<endl<<root.toStyledString()
     <<endl;
 
 return 0;
}

And this is the output:
$ g++ -o test_json test_json.cpp -ljson_linux-gcc-4.4.5_libmt
$ ./test_json 
Element 0 in array: item1
Element 1 in array: item2
Not an array: "asdf"

Json Example pretty print: 
{
   "array" : [ "item1", "item2" ],
   "not an array" : "asdf"
}

There are many other useful methods in JsonCpp's API.

Using a library like JsonCpp, we avoided all the parsing and could focus only on how to use the configuration data. This saved us a lot of time.

10 comments:

  1. hi, i'm find your article on google. I'm trying to compile your example code but i've received this error:

    main.cpp:34: undefined reference to `Json::Value::operator[](int) const'

    can help me? tnx

    ReplyDelete
    Replies
    1. Hi

      Humm, the line 34 in my code is a comment...
      I'd need to see your code to be able to help you.

      Best regards,
      M

      Delete
    2. I'm tryng with

      g++ -o main main.cpp -ljson_linux-gcc-4.6.1_libmt

      but I've received this error...uhmm there is a linking problem, but i don't understand why..

      /tmp/cc1ypcDP.o: In function `main':
      main.cpp:(.text+0x136): undefined reference to `Json::Value::operator[](int) const'
      collect2: ld returned 1 exit status

      Delete
    3. i found error... you must rewrite this part of code

      for (int index = 0; index < array.size(); index++) { // Iterates over the sequence elements.
      cout << "Element " << index << " in array: " << array[index].asString() << endl;
      }

      like:

      for (unsigned int index = 0; index < array.size(); index++) { // Iterates over the sequence elements.
      cout << "Element " << index << " in array: " << array[index].asString() << endl;
      }

      bye ;)

      Delete
    4. Hi

      Using
      g++ -o test_json test_json.cpp -ljson_linux-gcc-4.4.5_libmt
      the code in the post compiles fine.
      Perhaps the problem you found has to do with using a different version of the library.

      Anyway, I'm glad you found how to fix it. I'll change the code of the example so that it works with newer versions of JsonCpp.

      Thank you.

      Best regards,
      M

      Delete
  2. Hi,sorry :p ... incriminated line is number 32 exactly on "..array[index].asString()..." ... I'm using JsonCpp 0.5.0 from tar.gz (not svn)

    Tnx so much for your answer :)

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. hi i"m getting this error when compiling ljson_linux-gcc-4.4.5_libmt not found !!!

    ReplyDelete
  5. hey, may i know the jsoncpp.h file? bcoz i cant test it...
    i just copy all the code you given, thanks

    ReplyDelete
    Replies
    1. Hi You can get it from https://github.com/open-source-parsers/jsoncpp I explained how to install it here: http://garajeando.blogspot.com.es/2011/06/how-to-install-jsoncpp-in-ubuntu-and.html However that is an old post, so you'd be better off reading the documentation of JsonCpp.

      Delete