Search code examples
ccjson

cJSON to modify array of objects + adding additional values per object


I am currently having issues adding additional values to an array of objects. The iteration seems to work somehow, but I think I have to use the cjson_arrayforeach function differently or get rid of some loops. This my experimental code:

 cJSON *json = cJSON_Parse(buffer);
if (json == NULL) {
const char *error_ptr = cJSON_GetErrorPtr();
if (error_ptr != NULL) {
printf("Error: %s\n", error_ptr);
}
cJSON_Delete(json);
return 1;
}

cJSON *iterate = NULL;
cJSON *iterate = NULL;
cJSON_ArrayForEach(iterate,json) {
int count = 0 ;
while(count == 0) {

        cJSON *valuea = cJSON_GetObjectItemCaseSensitive(iterate,"valuea");
        cJSON *valueb = cJSON_GetObjectItemCaseSensitive(iterate, "valueb");
        for(int a = 0; a < cJSON_GetArraySize(json);a++) {

            if(cJSON_IsNumber(valuea)&&cJSON_GetNumberValue(valueb)==58) {

                int va = valuea->valueint;
                int va1 = va >> 8;
                int va2 = va & 256;
                if(a == 0) {
                    cJSON_AddNumberToObject(json->child,"va1",va1);
                    cJSON_AddNumberToObject(json->child,"va2",va2);


                }
                else {
                    cJSON_AddNumberToObject(json->child->next,"va1",va1);
                    cJSON_AddNumberToObject(json->child->next,"va2",va2);

                }
        

            }
        }
        count++;
    }
}

JSON Original

[{"valuea":5434,"Bytes":1,"valueb": 58},
  {"valuea":61578,"Bytes":1,"valueb": 58},
  {"valuea":61258,"Bytes":2,"valueb": 56}
]

And this is what was added to my JSON file

[{ "valuea":5434, "Bytes":  1, "valueb":58, "va1":21, 
"va2":  256, "va1": 240, "va2": 0 },
 { "valuea":61578, "Bytes": 1, "valueb":58, "va1":  21, 
"va2":  256, "va1": 21,
 "va2": 256, "va1": 240, "va2": 0,
 "va1": 240, "va2": 0 }, {
"valuea":   61258, "Bytes": 2, 
"valueb":   56 }]

There should be just one line of va1 & va2 per object.

Alternative code (a bit shortened)

 cJSON_ArrayForEach(iterate, json) {
        if(cJSON_IsNumber(cJSON_GetObjectItemCaseSensitive(iterate,"valuea"))&&cJSON_GetNumberValue(cJSON_GetObjectItemCaseSensitive(iterate,"valueb"))==58) {

            int va = cJSON_GetObjectItemCaseSensitive(iterate,"valuea")->valueint;
            int va1 = va >> 8;
            int va2 = va & 256;

            cJSON_AddNumberToObject(json->child,"va1",va1);
            cJSON_AddNumberToObject(json->child,"va2",va2);

        }
    }

resulting in this json

[{
        "valuea":   5434,
        "Bytes":    1,
        "valueb":   58,
        "va1":  21,
        "va2":  256,
        "va1":  240,
        "va2":  0
    }, {
        "valuea":   61578,
        "Bytes":    1,
        "valueb":   58
    }, {
        "valuea":   61258,
        "Bytes":    2,
        "valueb":   56
    }]

I am trying to modify a JSON in C and want to do a calculation for each JSON object. But the loop runs multiple times.


Solution

  • As @Diego Ferruchelli mentioned you should add the elements to iterate instead of json:

    #include <cJSON.h>
    #include <stdio.h>
    
    int main() {
        const char *buffer =
            "[{\"valuea\":5434,\"Bytes\":1,\"valueb\": 58},\n"
            "{\"valuea\":61578,\"Bytes\":1,\"valueb\": 58},\n"
            "{\"valuea\":61258,\"Bytes\":2,\"valueb\": 56}\n"
            "]";
        cJSON *json = cJSON_Parse(buffer);
        if (!json) {
            const char *error_ptr = cJSON_GetErrorPtr();
            if (error_ptr != NULL) {
                printf("Error: %s\n", error_ptr);
            }
            cJSON_Delete(json);
            return 1;
        }
        cJSON *iterate = NULL;
        cJSON_ArrayForEach(iterate, json) {
            cJSON *valuea = cJSON_GetObjectItemCaseSensitive(iterate,"valuea");
            cJSON *valueb = cJSON_GetObjectItemCaseSensitive(iterate, "valueb");
            if(cJSON_IsNumber(valuea) && cJSON_GetNumberValue(valueb) == 58) {
                int va = valuea->valueint;
                int va1 = va >> 8;
                int va2 = va & 256;
                cJSON_AddNumberToObject(iterate,"va1",va1);
                cJSON_AddNumberToObject(iterate,"va2",va2);
            }
        }
        printf("%s\n", cJSON_Print(json));
        cJSON_Delete(json);
    }
    

    and here is the expected output:

    [{
                    "valuea":       5434,
                    "Bytes":        1,
                    "valueb":       58,
                    "va1":  21,
                    "va2":  256
            }, {
                    "valuea":       61578,
                    "Bytes":        1,
                    "valueb":       58,
                    "va1":  240,
                    "va2":  0
            }, {
                    "valuea":       61258,
                    "Bytes":        2,
                    "valueb":       56
            }]