Skip to content

Examples

These are complete, self-contained programs. Only JsonLib.h needs to be included. Link against the JsonLib static library.

Round trip: JSON to struct and back

Parse a JSON document into a struct, modify it, and write it back out as indented JSON.

#include <stdio.h>
#include "JsonLib.h"

typedef struct
{
    char*       Name;
    uint32_t    Age;
    bool        Active;
} Person;

static JlMarshallElement PersonMap[] =
{
    JlMarshallString(   Person, Name,   "name" ),
    JlMarshallUnsigned( Person, Age,    "age" ),
    JlMarshallBool(     Person, Active, "active" ),
};
static size_t const PersonMapCount =
    sizeof(PersonMap) / sizeof(PersonMap[0]);

int main( void )
{
    char const* json = "{ \"name\": \"Ada\", \"age\": 36, \"active\": true }";

    // Parse the JSON into the struct.
    Person person = {0};
    size_t errorPos = 0;
    JL_STATUS status = JlJsonToStruct(
        json, PersonMap, PersonMapCount, &person, &errorPos );
    if( JL_STATUS_SUCCESS != status )
    {
        printf( "Parse failed at %zu (status %d)\n",
                errorPos, (int)status );
        return 1;
    }

    printf( "Name=%s Age=%u Active=%d\n",
            person.Name, person.Age, (int)person.Active );

    // Modify a field and write the struct back as indented JSON.
    person.Age += 1;

    char* output = NULL;
    status = JlStructToJson(
        &person, PersonMap, PersonMapCount, true, &output );
    if( JL_STATUS_SUCCESS == status )
    {
        printf( "%s\n", output );
        JlFreeJsonStringBuffer( &output );
    }

    // Free everything the parse allocated in the struct (Name).
    JlUnmarshallFreeStructAllocs( PersonMap, PersonMapCount, &person );
    return 0;
}

This prints:

{
    "name": "Ada",
    "age": 37,
    "active": true
}

Nested structs and arrays

A struct can contain another struct, allocated arrays of strings or numbers, and more. The input below uses JSON5 (bare keywords and single quotes), which is accepted by default.

#include <stdio.h>
#include "JsonLib.h"

typedef struct
{
    char*   Street;
    char*   City;
} Address;

typedef struct
{
    char*       Name;
    Address     Home;           // nested struct
    char**      Tags;           // allocated array of strings
    size_t      TagsCount;
    uint32_t*   Scores;         // allocated array of numbers
    size_t      ScoresCount;
} Profile;

static JlMarshallElement AddressMap[] =
{
    JlMarshallString( Address, Street, "street" ),
    JlMarshallString( Address, City,   "city" ),
};
static size_t const AddressMapCount =
    sizeof(AddressMap) / sizeof(AddressMap[0]);

static JlMarshallElement ProfileMap[] =
{
    JlMarshallString( Profile, Name, "name" ),
    JlMarshallStruct( Profile, Home, "home",
                      AddressMap, AddressMapCount ),
    JlMarshallStringArray( Profile, Tags, TagsCount, "tags" ),
    JlMarshallUnsignedArray( Profile, Scores, ScoresCount, "scores" ),
};
static size_t const ProfileMapCount =
    sizeof(ProfileMap) / sizeof(ProfileMap[0]);

int main( void )
{
    char const* json =
        "{"
        "  name: 'Grace',"
        "  home: { street: '1 Navy Way', city: 'Arlington' },"
        "  tags: [ 'admin', 'ops' ],"
        "  scores: [ 10, 20, 30 ]"
        "}";

    Profile profile = {0};
    size_t errorPos = 0;
    JL_STATUS status = JlJsonToStruct(
        json, ProfileMap, ProfileMapCount, &profile, &errorPos );
    if( JL_STATUS_SUCCESS != status )
    {
        printf( "Parse failed at %zu\n", errorPos );
        return 1;
    }

    printf( "%s lives in %s. %zu tags, %zu scores.\n",
            profile.Name, profile.Home.City,
            profile.TagsCount, profile.ScoresCount );

    JlUnmarshallFreeStructAllocs( ProfileMap, ProfileMapCount, &profile );
    return 0;
}

Controlling the output format

JlStructToJsonEx takes a set of flags. Combine them to choose indentation, JSON5 features, and more. For example, to produce compact JSON5 with bare keywords and single quotes:

char* output = NULL;
JL_STATUS status = JlStructToJsonEx(
    &person, PersonMap, PersonMapCount,
    JL_OUTPUT_FLAGS_J5_USE_BARE_KEYWORDS
        | JL_OUTPUT_FLAGS_J5_SINGLE_QUOTES,
    &output );
if( JL_STATUS_SUCCESS == status )
{
    printf( "%s\n", output );    // {name:'Ada',age:37,active:true}
    JlFreeJsonStringBuffer( &output );
}

See the Functions page for the full list of output flags.