C/C++ JSON Parser

Parsing JSON using C

Json isn't a huge language to start with, so libraries for it are likely to be small(er than Xml libraries, at least).

There are a whole ton of C libraries linked at Json.org. Maybe one of them will work well for you.

JsonParser in C with json-c Library | json_object_object_get(...) not declared

The json_object_object_get_ex() function returns a json_bool (which is actually an int) indicating whether the given key is found in the parent JSON object, so you can't assign the function return value to jobj, which is a pointer: that's where the warning comes from.

Since in your code you already have a pointer (in the val variable) to the JSON object corresponding to a given key, you can achieve what you want more simply by avoiding the call to json_object_object_get_ex() and calling json_parse(val).

Parsing JSON array in C

Thanks @wiseveri for the tip, managed to access the values section with the following:

// gcc json_c_test.c -ljson-c -o json_c_test && clear && ./json_c_test

#include <json/json.h>
#include <stdio.h>

void json_parse_input( json_object *jobj )
{
int exists, i, j, k, l;
char *results;
json_object *queriesObj, *resultsObj, *valuesObj, *tmpQueries, *tmpResults, *tmpValues, *tmpSeparateVals;

/* Get query key */
exists = json_object_object_get_ex( jobj, "queries", &queriesObj );
if ( FALSE == exists )
{
printf( "\"queries\" not found in JSON\n" );
return;
}

/* Loop through array of queries */
for ( i = 0; i < json_object_array_length( queriesObj ); i++ )
{
tmpQueries = json_object_array_get_idx( queriesObj, i );

/* Get results info */
exists = json_object_object_get_ex( tmpQueries, "results", &resultsObj );
if ( FALSE == exists )
{
printf( "\"results\" not found in JSON\n" );
return;
}

/* Loop through array of results */
for ( j = 0; j < json_object_array_length( resultsObj ); j++ )
{
tmpResults = json_object_array_get_idx ( resultsObj, j );

/* Get values */
exists = json_object_object_get_ex( tmpResults, "values", &valuesObj );
if ( FALSE == exists )
{
printf( "\"values\" not found in JSON\n" );
return;
}

/* Loop through array of array of values */
for ( k = 0; k < json_object_array_length( valuesObj ); k++ )
{
tmpValues = json_object_array_get_idx ( valuesObj, k );

/* Loop through array of values */
for ( l = 0; l < json_object_array_length( tmpValues ); l++ )
{
tmpSeparateVals = json_object_array_get_idx ( tmpValues, l );
printf( "Values:[%d] = %s \n", l, json_object_to_json_string( tmpSeparateVals ) );
}
}
}
}
}

int main()
{
json_object *jobj;

char * string = " { \"queries\" : [ { \"sample_size\" : 1, \"results\" : [ { \"name\" : \"data\", \"group_by\" : [{ \"name\" : \"type\", \"type\" : \"number\" }], \"tags\" : { \"hostname\" : [ \"host\" ]}, \"values\": [[1438775895302, 143]] } ], } ] } ";
printf ( "JSON string: %s\n\n", string );

jobj = json_tokener_parse( string );
json_parse_input( jobj );
}

Parse json file using json-c

It's a bit funny that you ask about json-c, which I just picked up for my own purposes a short time ago. Anyway, the problem is certainly what @Myst described in comments.

I was able to duplicate the problem you describe, and running the program under a debugger immediately showed that the segfault occurs during the iteration, not the parse.

Looking a bit more closely at the code, then, in light of the package's naming conventions, the function (macro, actually) json_object_object_foreach() is designated for use with objects representing JSON objects, not JSON arrays. That's the significance of the second "object" in the name. You must not apply that macros to an object representing a JSON array, as you try to do when the top-level JSON structure in your input is an array. It follows that you must test what type of object you have before determining how to examine it.

You can determine the type of object you have via json_object_get_type() or json_object_is_type(). For a top-level array, you can get the array length via json_object_array_length(), and use an ordinary for loop to iterate over the index range, retrieving elements via json_object_array_get_idx(). I don't presently see any better alternative, but perhaps someone more experienced with the library will have one to offer.

JSON parsing using C

Check frozen library https://github.com/cesanta/frozen is tiny, portable and without dependencies.

For your case here the solution:

#include <stdio.h>

#include "frozen.c"

static void scan_array(const char *str, int len, void *user_data) {
struct json_token t;
int i;
float price;
int casted;

printf("Parsing array: %.*s\n", len, str);
for (i = 0; json_scanf_array_elem(str, len, "", i, &t) > 0; i++) {
printf("Index %d, token %.*s\n", i, t.len, t.ptr);
json_scanf(t.ptr, t.len, "{price: %f}", &price);
casted = (int)price;
printf("Price %.2f : price casted %d \n", price, casted);

}
}

int main(void) {

const char *str =
"{\"success\":true,\"errors\":[],\"results\":[{\"productConditionId\":3442759,\"price\":169.54,\"lowestRange\":155.00,\"highestRange\":229.95}]}";

printf("Parsing %s \n", str);
json_scanf(str, strlen(str), "{results: [%M]}", &scan_array);

return 0;
}

Output:

Parsing {"success":true,"errors":[],"results":[{"productConditionId":3442759,"price":169.54,"lowestRange":155.00,"highestRange":229.95}]} 
Parsing array: [{"productConditionId":3442759,"price":169.54,"lowestRange":155.00,"highestRange":229.95}]
Index 0, token {"productConditionId":3442759,"price":169.54,"lowestRange":155.00,"highestRange":229.95}
Price 169.54 : price casted 169


Related Topics



Leave a reply



Submit