我正在尝试使用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;
}
我需要分别解析所有字符串及其值,然后打印出来。有人可以请教吗?
问候。
答案 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