cJSON库学习——C语言结构体与JSON互相转换
跟着这两个教程学习的:
运行结果:
该代码展示了如何将一段以字符串形式表示的JSON串转换为cJSON的结构并进行解析,接下来是如何通过代码创建cJSON结构体:
#include <stdio.h> #include "cJSON.h" int main() { //通过cJSON_CreateObject创建根节点,通过cJSON_CreateArray创建数组 //通过cJSON_AddItemToObject向一个节点添加元素,通过cJSON_AddItemToArray向数组添加元素 cJSON* pRoot = cJSON_CreateObject(); cJSON* pArray = cJSON_CreateArray(); cJSON_AddItemToObject(pRoot, "students_info", pArray); cJSON* pItem = cJSON_CreateObject(); cJSON_AddStringToObject(pItem, "name", "chenzhongjing"); cJSON_AddStringToObject(pItem, "sex", "male"); cJSON_AddNumberToObject(pItem, "age", 28); cJSON_AddItemToArray(pArray, pItem); pItem = cJSON_CreateObject(); cJSON_AddStringToObject(pItem, "name", "fengxuan"); cJSON_AddStringToObject(pItem, "sex", "male"); cJSON_AddNumberToObject(pItem, "age", 24); cJSON_AddItemToArray(pArray, pItem); pItem = cJSON_CreateObject(); cJSON_AddStringToObject(pItem, "name", "tuhui"); cJSON_AddStringToObject(pItem, "sex", "male"); cJSON_AddNumberToObject(pItem, "age", 22); cJSON_AddItemToArray(pArray, pItem); char* szJSON = cJSON_Print(pRoot);//通过cJSON_Print获取cJSON结构体的字符串形式(注:存在\n\t) printf(szJSON); cJSON_Delete(pRoot); free(szJSON); return 0; }
运行结果:
要注意的是产生的字符串中存在较多的\n与\t,如果不需要的话需要后期进行处理。
通过这两段代码,就可以借助cJSON库来实现字符串与cJSON结构体的互相转换。C语言结构体与JSON可以通过cJSON结构体来进行中转,从而实现之间的转换。以下为一个范例:
#include <stdio.h> #include "cJSON.h" typedef struct _c_struct_t{ unsigned char a; unsigned short b; unsigned int c; unsigned long long d; float e; }c_struct_t; int main() { //创建JSON串:{"uint_8":8,"uint_16":16,"uint_32":32,"uint_64":64,"float":6.13141516} //其中float格式故意越界初始化 c_struct_t testStruct1 = { 255,16,32,64,6.13141516 }; c_struct_t testStruct2 = { 0 }; cJSON* pRoot = cJSON_CreateObject(); cJSON_AddNumberToObject(pRoot, "uint_8", testStruct1.a); cJSON_AddNumberToObject(pRoot, "uint_16", testStruct1.b); cJSON_AddNumberToObject(pRoot, "uint_32", testStruct1.c); cJSON_AddNumberToObject(pRoot, "uint_64", testStruct1.d); cJSON_AddNumberToObject(pRoot, "float", testStruct1.e); char* szJSON = cJSON_Print(pRoot);//通过cJSON_Print获取cJSON结构体的字符串形式(注:存在\n\t) printf(szJSON); printf("\n"); cJSON* root = cJSON_Parse(szJSON); testStruct2.a = cJSON_GetObjectItem(root, "uint_8")->valueint; testStruct2.b = cJSON_GetObjectItem(root, "uint_16")->valueint; testStruct2.c = cJSON_GetObjectItem(root, "uint_32")->valueint; testStruct2.d = cJSON_GetObjectItem(root, "uint_64")->valueint; testStruct2.e = cJSON_GetObjectItem(root, "float")->valuedouble; printf("%u\n%u\n%u\n%llu\n%f\n", testStruct2.a, testStruct2.b, testStruct2.c, testStruct2.d, testStruct2.e); return 0; }
运行结果:
可以看到float格式存储的数据从6.13141516变成了这么一长串的数字,实际上在赋值后数值为6.13141537。这就是单精度的存储范围问题,以及单精度双精度转换的问题。在CJSON结构体中存储数值时时以int格式存储的,所以会产生这样的问题。而在转换为结构体中的float时,由于精度问题,只保留到小数点后第6位。
代码中可以看到无论cJSON结构体的解析还是封装都是挨个书写的,这主要还是因为c语言中没有反射机制,自己写反射机制有点难。所以目前以我的水平只能写成这样,一种结构体一种转换函数。
以上。