Write and Parse JSON in C

CParse JSON in CWrite JSON in C

C does not support native JSON parsers and creators. Many JSON libraries are available in C like json-c, cJSON, and much more. In this blog, we will go with cJSON to read and write JSON in C. Let's Consider the following sample JSON Document which consists of JSON Object, JSON Array, and key-value pair forms :

{
    "name" : "File.mp3",
    "size" : "25Mb",
    "section" : [ 1 , 2, 3 , 4 ],
    "updateby" : [
     {
         "name" : "user one",
         "date" : "10:00 21 May",
         "userrole" : [ "add", "update", "delete"]
     },
     {
         "name" : "user two",
         "date" : "10:00 21 May",
         "userrole" : [ "add", "delete"]
     }],
    "Metadata" : { "create" : "21 MAy", "audio" : "acc", "video" : "H264"}
}

Setup

Click here to get the latest cJSON. Download the zip file, Once it's done we can use it as a library or include .c and .h in our project. cJSON comes with many different options which can change by passing CMAKE In source code we include some of the flags in the makefile.

#include "cJSON/cJSON.h"


Write JSON in C

STEP 1: To write JSON, First you need to include a cJSON.c and cJSON.h in your project directory. cJSON is a struct data type and working with this data type cJAON provides different functions, for example, cJSON_Create* method can be used to create respective types like Objects, arrays or references.

#include "cJSON/cJSON.h"

cJSON *jsonData = cJSON_CreateObject();
cJSON *jsonDataArray = cJSON_CreateArray();

STEP 2: To insert key value pair, we can use cJSON_Add*ToObject methods.

cJSON_AddItemToObject(jsonData, "section", cJSON_CreateIntArray(intArray, 4));
cJSON_AddStringToObject(jsonDataObj_one, "name", "user one");

STEP 3: To create JSON Array, cJSON provides cJSON_CreateIntArray(), cJSON_CreateFloatArray(), cJSON_CreateDoubleArray(), cJSON_CreateStringArray() methods. We are required to pass an array and its count correctly otherwise it will jump into out-of-bound exceptions.

const char *role_two[2] = {
  "add",
  "delete"
};

cJSON_AddItemToObject(jsonDataObj_two, "userrole", cJSON_CreateStringArray(role_two, 2));

STEP 4: Similarly, we can create nested JSON, with the help of cJSON_AddItemToObject function :

cJSON_AddItemToObject(jsonData, "Metadata", jsonDataObj_metadata);
cJSON_AddStringToObject(jsonDataObj_metadata, "create", "21 May");
cJSON_AddStringToObject(jsonDataObj_metadata, "audio", "acc");
cJSON_AddStringToObject(jsonDataObj_metadata, "video", "H264");

Let’s see a complete code of write JSON data in C :

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "simpleCJson.h"
#include "cJSON/cJSON.h"

cJSON* writeJson(void) {

  printf("Let's write/create JSON in c by using cJSON");

  /* declare JSON Object. */
  cJSON *jsonData = cJSON_CreateObject();
  cJSON *jsonDataObj_one = cJSON_CreateObject();
  cJSON *jsonDataObj_two = cJSON_CreateObject();
  cJSON *jsonDataObj_metadata = cJSON_CreateObject();

  /* declare JSON Arrays. */
  cJSON *jsonDataArray = cJSON_CreateArray();

  /* Creating a JSON Array */
  int intArray[4] = { 1, 2, 3, 4 };

  /* array of strings */
  const char *role_one[3] =
  {
      "add",
      "update",
      "delete"
  };

  const char *role_two[2] =
  {
      "add",
      "delete"
  };

  cJSON_AddItemToObject(jsonData, "name", cJSON_CreateString("File.mp3"));
  cJSON_AddItemToObject(jsonData, "size", cJSON_CreateString("25Mb"));
  cJSON_AddItemToObject(jsonData, "section", cJSON_CreateIntArray(intArray, 4));

  cJSON_AddItemToObject(jsonDataArray, "updateby", jsonDataObj_one);
  cJSON_AddStringToObject(jsonDataObj_one, "name", "user one");
  cJSON_AddStringToObject(jsonDataObj_one, "date", "10:00 21 May");

  /*Creating a JSON Array*/
  cJSON_AddItemToObject(jsonDataObj_one, "userrole", cJSON_CreateStringArray(role_one, 3));

  cJSON_AddItemToObject(jsonDataArray, "updateby", jsonDataObj_two);
  cJSON_AddStringToObject(jsonDataObj_two, "name", "user two");
  cJSON_AddStringToObject(jsonDataObj_two, "date", "10:00 21 May");

  cJSON_AddItemToObject(jsonDataObj_two, "userrole", cJSON_CreateStringArray(role_two, 2));

  /*Add Json Object array in Json*/
  cJSON_AddItemToObject(jsonData, "updateby", jsonDataArray);

  cJSON_AddItemToObject(jsonData, "Metadata", jsonDataObj_metadata);
  cJSON_AddStringToObject(jsonDataObj_metadata, "create", "21 May");
  cJSON_AddStringToObject(jsonDataObj_metadata, "audio", "acc");
  cJSON_AddStringToObject(jsonDataObj_metadata, "video", "H264");

  printf("Output JSON : ", cJSON_Print(jsonData));

  return jsonData;
}


Parse JSON in C

STEP 1: To parse JSON, we can parse JSON with cJSON_Parse() method.

char *_jsondata  = "{"name":"File.mp3","size":"25Mb","section":[1,2,3,4],"updateby":[{"name":"user one","date":"10:00 21 May","userrole":["add","update","delete"]},{"name":"user two","date":"10:00 21 May","userrole":["add","delete"]}],"Metadata":{"create":"21 MAy","audio":"acc","video":"H264"}}";

// parse char pointer in JSON Object
cJSON *json = cJSON_Parse(string);

STEP 2: To extract respective string objects we can use cJSON_GetObjectItem method.

const cJSON *_data = cJSON_GetObjectItemCaseSensitive(jsonData, "size");

STEP 3: To identify primitive data types, cJSON support cJSON_Is*() methods.

//To Identify String
cJSON_IsString(_data);

//To Identify Object
cJSON_IsObject(_data);

Let’s see a complete code of parse JSON data in C:

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "simpleCJson.h"
#include "cJSON/cJSON.h"

void parserJson(cJSON *jsondata) {

  printf("Let's read key and value from JSON string in c by using cJSON.");

  const cJSON *_data = NULL;
  const cJSON *_dataObj = NULL;

  /*Converting cjson json to string*/
  char *_jsondata = cJSON_Print(jsondata);

  /* Parse cJSON */
  cJSON *jsonData = cJSON_Parse(_jsondata);

  /*Get string from JSON object*/
  _data = cJSON_GetObjectItemCaseSensitive(jsonData, "name");
  if (cJSON_IsString(_data) && (_data->valuestring != NULL))
  {
    printf("	Key : 'name' | Value : "%s"", _data->valuestring);
  }

  /*Get string from JSON object*/
  _data = cJSON_GetObjectItemCaseSensitive(jsonData, "size");
  if (cJSON_IsString(_data) && (_data->valuestring != NULL))
  {
    printf("	Key : 'size' | Value : "%s"", _data->valuestring);
  }

  /*Get array from JSON object*/
  _data = cJSON_GetObjectItemCaseSensitive(jsonData, "section");
  if (cJSON_IsArray(_data))
  {
    printf("	Key : 'section'");
    int i = 0;
    for (i = 0 ; i < cJSON_GetArraySize(_data) ; i++)
    {
      printf("		Index : '%d' | Value : %d ",cJSON_GetArrayItem(_data, i)->valueint);
    }
  }

  /*Get Object from JSON Array */
  _data = cJSON_GetObjectItemCaseSensitive(jsonData, "updateby");
  if (cJSON_IsArray(_data))
  {
    int i = 0;
    for (i = 0 ; i < cJSON_GetArraySize(_data) ; i++)
    {
      _dataObj = cJSON_GetArrayItem(_data, i);
      printf("	Key : 'updateby' | Value : %s ",cJSON_Print(_dataObj));
    }
  }

  _data = cJSON_GetObjectItemCaseSensitive(jsonData, "Metadata");
  if (cJSON_IsObject(_data)) {
    printf("	Key : 'Metadata' | Value : %s ",cJSON_Print(_data));
  }


  cJSON_Delete(jsonData);
}

Download


cJSON library : Click here

Source Code : Click here

Credits


cJSON library - CPP JSON encoders/decoders library

json.org - Introducing JSON Standard