cJSON解析建议

时间:2018-02-06 10:34:26

标签: c json microcontroller cjson

我正在尝试使用CJSON解析我的微控制器代码中的以下JSON字符串。

    {
    "A":
        {
            "A1":
                [
                    {"S":0,"V":-5},
                    {"S":60,"V":5}
                ],
            "A2":
                [
                    {"S":0,"V":-5},
                    {"S":60,"V":5}
                ]
        },
    "B":
        {
            "B1":
                [
                    {"S":0,"V":-5},
                    {"S":60,"V":5}
                ],
            "B2":
                [
                    {"S":0,"V":-5},
                    {"S":60,"V":5}
                ]
        },
    "C":60
}

到目前为止,我尝试过滤A的字符串。然后我可以再次运行解析来从A过滤A1。代码没有用。它打印'error_ptr'。

int cJSON_Test()
{
    char text[1024];

    char JSON_STRING[] =
    "{\n"
    "\"A\":{\"A1\":[{\"S\":0,\"V\":-5},{\"S\":60,\"V\":5}],\"A2\":[{\"S\":0,\"V\":-5},{\"S\":60,\"V\":5}]},\n"
    "\"B\":{\"B1\":[{\"S\":0,\"V\":-5},{\"S\":60,\"V\":5}],\"B2\":[{\"S\":0,\"V\":-5},{\"S\":60,\"V\":5}]},\n"
    "\"C\":60\n"
    "}";

    const cJSON *A_Data = NULL;
    const cJSON *B_Data = NULL;
    const cJSON *C_Data = NULL;

    const cJSON *A1_Data = NULL;
    const cJSON *A2_Data = NULL;

  int status = 0;
  cJSON *root = cJSON_Parse(JSON_STRING);
  if (root == NULL)
  {
    const char *error_ptr = cJSON_GetErrorPtr();
    if (error_ptr != NULL)
    {
            sprintf(text,"Error before: %s\r\n", error_ptr);
            SendDataToUart(&huart1, (uint8_t*)text, strlen(text));

    }
    status = 0;
    goto end;
  }

    A_Data = cJSON_GetObjectItemCaseSensitive(root, "A");
    if (cJSON_IsString(A_Data) && (A_Data->valuestring != NULL))
    {
        sprintf(text,"A String: %s\r\n", A_Data->valuestring);
        SendDataToUart(&huart1, (uint8_t*)text, strlen(text));
    }

    end:
    cJSON_Delete(root);
    return status;
}

我需要分别解析所有字符串及其值,然后打印出来。有人可以请教吗?

问候。

1 个答案:

答案 0 :(得分:0)

您可以通过创建使用cJSON_InitHooks安装的包装来调试分配器的问题。

我写了一个示例,说明如何解析您的输入以及一些调试分配器,这应该可以帮助您找到问题。只需用函数替换所有Cannot access protected property... s,即可通过UART发送字符串。

printf

在我的x86_64机器上运行时,它会输出以下内容:

#include <cjson/cJSON.h>
#include <stdio.h>
#include <stdlib.h>

size_t total_allocated = 0;

void *debugging_malloc(size_t size) {
    void *pointer = malloc(size);
    if (pointer == NULL) {
        printf("Failed to allocate %zu bytes\n", size);
    } else {
        total_allocated += size;
        printf("Allocated %zu bytes: %p\n", size, pointer);
    }

    return pointer;
}

void debugging_free(void *pointer) {
    free(pointer);
    printf("Freed %p\n", pointer);
}

cJSON_Hooks debugging_allocators = {debugging_malloc, debugging_free};

int print_s_v_array(const cJSON *array, const char *name) {
    const cJSON *element = NULL;
    size_t index = 0;
    printf("\t%s: [", name);
    cJSON_ArrayForEach(element, array) {
        cJSON *S = NULL;
        cJSON *V = NULL;

        if (!cJSON_IsObject(element)) {
            return 0;
        }

        S = cJSON_GetObjectItemCaseSensitive(element, "S");
        if (!cJSON_IsNumber(S)) {
            return 0;
        }

        V = cJSON_GetObjectItemCaseSensitive(element, "V");
        if (!cJSON_IsNumber(V)) {
            return 0;
        }

        printf("\t%zu: S is %f and V is %f\n", index, S->valuedouble, V->valuedouble);

        index++;
    }
    printf("\t]\n");

    return 1;
}

cJSON_bool print_sub_object(const cJSON *object, const char *name) {
    cJSON *element = NULL;
    printf("%s: {\n", name);
    cJSON_ArrayForEach(element, object) {
        if (!cJSON_IsArray(element) || (element->string == NULL)) {
            return 0;
        }

        print_s_v_array(element, element->string);
    }
    printf("}\n");

    return 1;
}

int main() {
    char JSON_STRING[] =
    "{\n"
    "\"A\":{\"A1\":[{\"S\":0,\"V\":-5},{\"S\":60,\"V\":5}],\"A2\":[{\"S\":0,\"V\":-5},{\"S\":60,\"V\":5}]},\n"
    "\"B\":{\"B1\":[{\"S\":0,\"V\":-5},{\"S\":60,\"V\":5}],\"B2\":[{\"S\":0,\"V\":-5},{\"S\":60,\"V\":5}]},\n"
    "\"C\":60\n"
    "}";

    const cJSON *A = NULL;
    const cJSON *B = NULL;
    const cJSON *C = NULL;
    const cJSON *A1 = NULL;
    const cJSON *A2 = NULL;
    const cJSON *B1 = NULL;
    const cJSON *B2 = NULL;
    const cJSON *element = NULL;
    size_t index = 0;

    int status = EXIT_SUCCESS;

    cJSON_InitHooks(&debugging_allocators);

    cJSON *root = cJSON_Parse(JSON_STRING);
    if (root == NULL) {
        const char *error_ptr = cJSON_GetErrorPtr();
        if (error_ptr != NULL) {
            printf("Error before: %s\r\n", error_ptr);
        }
        goto fail;
    }

    A = cJSON_GetObjectItemCaseSensitive(root, "A");
    if (!cJSON_IsObject(A)) {
        goto fail;
    }
    print_sub_object(A, "A");
    /* you could of course just get A1 and A2 via cJSON_GetObjectItemCaseSensitive manually
     * instead of making such a function, not sure what you actually want to do with your data */


    B = cJSON_GetObjectItemCaseSensitive(root, "B");
    if (!cJSON_IsObject(B)) {
        goto fail;
    }
    print_sub_object(B, "B");

    C = cJSON_GetObjectItemCaseSensitive(root, "C");
    if (!cJSON_IsNumber(C)) {
        goto fail;
    }
    printf("C: %f\n", C->valuedouble);

    goto end;

fail:
    status = EXIT_FAILURE;
end:
        cJSON_Delete(root);
        printf("Allocated in total: %zu bytes\n", total_allocated);
        return status;
}

如果您想要打印,例如Allocated 64 bytes: 0xf14a51915d0 Allocated 64 bytes: 0xf14a5192630 Allocated 3 bytes: 0xf14a5192680 Allocated 64 bytes: 0xf14a51926a0 Allocated 4 bytes: 0xf14a51926f0 Allocated 64 bytes: 0xf14a5192710 Allocated 64 bytes: 0xf14a5192760 Allocated 3 bytes: 0xf14a51927b0 Allocated 64 bytes: 0xf14a51927d0 Allocated 3 bytes: 0xf14a5192820 Allocated 64 bytes: 0xf14a5192840 Allocated 64 bytes: 0xf14a5192890 Allocated 3 bytes: 0xf14a51928e0 Allocated 64 bytes: 0xf14a5192900 Allocated 3 bytes: 0xf14a5192950 Allocated 64 bytes: 0xf14a5192970 Allocated 4 bytes: 0xf14a51929c0 Allocated 64 bytes: 0xf14a51929e0 Allocated 64 bytes: 0xf14a5192a30 Allocated 3 bytes: 0xf14a5192a80 Allocated 64 bytes: 0xf14a5192aa0 Allocated 3 bytes: 0xf14a5192af0 Allocated 64 bytes: 0xf14a5192b10 Allocated 64 bytes: 0xf14a5192b60 Allocated 3 bytes: 0xf14a5192bb0 Allocated 64 bytes: 0xf14a5192bd0 Allocated 3 bytes: 0xf14a5192c20 Allocated 64 bytes: 0xf14a5192c40 Allocated 3 bytes: 0xf14a5192c90 Allocated 64 bytes: 0xf14a5192cb0 Allocated 4 bytes: 0xf14a5192d00 Allocated 64 bytes: 0xf14a5192d20 Allocated 64 bytes: 0xf14a5192d70 Allocated 3 bytes: 0xf14a5192dc0 Allocated 64 bytes: 0xf14a5192de0 Allocated 3 bytes: 0xf14a5192e30 Allocated 64 bytes: 0xf14a5192e50 Allocated 64 bytes: 0xf14a5192ea0 Allocated 3 bytes: 0xf14a5192ef0 Allocated 64 bytes: 0xf14a5192f10 Allocated 3 bytes: 0xf14a5192f60 Allocated 64 bytes: 0xf14a5192f80 Allocated 4 bytes: 0xf14a5192fd0 Allocated 64 bytes: 0xf14a5192ff0 Allocated 64 bytes: 0xf14a5193040 Allocated 3 bytes: 0xf14a5193090 Allocated 64 bytes: 0xf14a51930b0 Allocated 3 bytes: 0xf14a5193100 Allocated 64 bytes: 0xf14a5193120 Allocated 64 bytes: 0xf14a5193170 Allocated 3 bytes: 0xf14a51931c0 Allocated 64 bytes: 0xf14a51931e0 Allocated 3 bytes: 0xf14a5193230 Allocated 64 bytes: 0xf14a5193250 Allocated 3 bytes: 0xf14a51932a0 A: { A1: [ 0: S is 0.000000 and V is -5.000000 1: S is 60.000000 and V is 5.000000 ] A2: [ 0: S is 0.000000 and V is -5.000000 1: S is 60.000000 and V is 5.000000 ] } B: { B1: [ 0: S is 0.000000 and V is -5.000000 1: S is 60.000000 and V is 5.000000 ] B2: [ 0: S is 0.000000 and V is -5.000000 1: S is 60.000000 and V is 5.000000 ] } C: 60.000000 Freed 0xf14a51927b0 Freed 0xf14a5192760 Freed 0xf14a5192820 Freed 0xf14a51927d0 Freed 0xf14a5192710 Freed 0xf14a51928e0 Freed 0xf14a5192890 Freed 0xf14a5192950 Freed 0xf14a5192900 Freed 0xf14a5192840 Freed 0xf14a51926f0 Freed 0xf14a51926a0 Freed 0xf14a5192a80 Freed 0xf14a5192a30 Freed 0xf14a5192af0 Freed 0xf14a5192aa0 Freed 0xf14a51929e0 Freed 0xf14a5192bb0 Freed 0xf14a5192b60 Freed 0xf14a5192c20 Freed 0xf14a5192bd0 Freed 0xf14a5192b10 Freed 0xf14a51929c0 Freed 0xf14a5192970 Freed 0xf14a5192680 Freed 0xf14a5192630 Freed 0xf14a5192dc0 Freed 0xf14a5192d70 Freed 0xf14a5192e30 Freed 0xf14a5192de0 Freed 0xf14a5192d20 Freed 0xf14a5192ef0 Freed 0xf14a5192ea0 Freed 0xf14a5192f60 Freed 0xf14a5192f10 Freed 0xf14a5192e50 Freed 0xf14a5192d00 Freed 0xf14a5192cb0 Freed 0xf14a5193090 Freed 0xf14a5193040 Freed 0xf14a5193100 Freed 0xf14a51930b0 Freed 0xf14a5192ff0 Freed 0xf14a51931c0 Freed 0xf14a5193170 Freed 0xf14a5193230 Freed 0xf14a51931e0 Freed 0xf14a5193120 Freed 0xf14a5192fd0 Freed 0xf14a5192f80 Freed 0xf14a5192c90 Freed 0xf14a5192c40 Freed 0xf14a51932a0 Freed 0xf14a5193250 Freed 0xf14a51915d0 Allocated in total: 2121 bytes ,您可以使用A。请阅读文档here

cJSON_Print

或者在这种情况下,因为您需要打印到缓冲区以便通过UART发送它,您可以使用char *printed_a = cJSON_Print(A); if (printed_a == NULL) { goto fail; } printf("%s\n", printed_a); free(printed_a);

cJSON_PrintPreallocated