PaulPonomarev
PaulPonomarev

Reputation: 373

CCAN JSON Serialization in C

I'm using JSON library. It's quite light and easy to understand, but I have one problem with json_decode. I'm reading data(JSON) from file:

FILE *instream = fopen("/tmp/file.dat", "r");
char ch;
int count = 0;
do {
    ch = getc(instream);
    inbuffer[count] = ch;
count++;
} while (!feof(instream) && ch != '\0');

My file look like below, so inbuffer has the same text

[
        {
                "MBV": 0,
                "CRRC": 0,
                "LFrei": 0
        }                
]

I try to decode it to have JsonNode variable

static char *chomp(char *s) //function taken from CCAN JSON example
{
    char *e;
    if (s == NULL || *s == 0)
        return s;

    e = strchr(s, 0);
    if (e[-1] == '\n')
        *--e = 0;
    return s;
}

const char *s = chomp(inbuffer);
JsonNode *jin = json_decode(s);
printf("JSON: %s\n", jin);

After I run my program I get

JSON: (null)

Can somebody tell me why json_decode function doesn't want to read JSON formatted file even if the file created using this library?

Upvotes: 2

Views: 964

Answers (2)

asamarin
asamarin

Reputation: 1594

This code prints all the key-value pairs found in the first object of the array (your example shows an array containing only one object, which in turn contains three key-value items):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ccan/json/json.h>

int main(int argc, char **argv)
{
    FILE *fd;
    long filesize;
    char *buffer;
    JsonNode *jin, *node;

    if ((fd = fopen(argv[1], "r")) == NULL) {
        perror("Error opening file");
        return EXIT_FAILURE;
    }

    fseek(fd, 0, SEEK_END);
    filesize = ftell(fd);
    rewind(fd);

    buffer = (char *) malloc(sizeof(char) * filesize+1);

    if (fread(buffer, sizeof(char), filesize, fd) != filesize) {
        fprintf(stderr, "Error reading file\n");
        return EXIT_FAILURE;
    }

    buffer[filesize] = '\0';

    jin = json_decode(buffer);
    json_foreach(node, jin->children.head)
        printf("%s: %g\n", node->key, node->number_);

    free(buffer);

    return EXIT_SUCCESS;
}

Take into account that the traversal I just did heavily depends on the structure of the JSON you're trying to parse. If it fits your needs, fine, but maybe you'll need to find a more general solution. Take a look at the json.h header file included with the library to understand how the JSON structure is stored in memory once decoded from the file.

Also, in my personal experience, I've found the JSON-C library much easier to use than this one.

Upvotes: 2

Ingo Leonhardt
Ingo Leonhardt

Reputation: 9894

I don't know the JSON library you ar using but I suspect the error occurs because inbuffer is not correctly NUL terminated. On end of file, getc() returns EOF (-1) what you copy into inbuffer before feof() returns TRUE. I would do:

while( (ch = getc( instream )) != EOF ) {
   inbuffer[count] = ch;
   count++;
}
inbuffer[count] = '\0';

or just use fread():

count = fread( inbuffer, 1, sizeof( inbuffer ) - 1, stream );
inbuffer[count] = '\0';

Upvotes: 2

Related Questions