1、说明
qt明明有QJson模块,为什么还需要使用cJson?
开始我也想qt怎么会需要cjson,肯定会自带json相关处理解析类,后来遇到了使用qt4开发嵌入式设备程序,发现怎么也找不到QJson相关的类…,查资料才知道,QJson模块是在qt5之后才添加的,所以qt4没有这个模块,于是cJSON这个非常简明(短小精悍)的json文件处理库就进入了视野。
cJSON源码解读:https://blog.csdn.net/weixin_42887343/article/details/111571999
cJson的源代码链接(github): https://github.com/DaveGamble/cJSON
2、cJson源码下载
依据上述下载链接,去github下载源代码,如何别看项目文件那么多,其实只有下图的两个文件对你有用。当然其他文件也有用处,只是我们这里不需要。
3、把下载的项目中cJSON.c和cJSON.h文件拷贝到你的项目下面。
(1)使用qtcreator为例子,项目源代码下新建cJson文件夹,把两个文件放这个文件夹下面。
(2)右键项目点击添加现有文件,让后把cJSON.c和cJSON.h两个文件添加到项目中。
4、代码运用
源码中核心结构体如下:
/* The cJSON structure: */
typedef struct cJSON
{
struct cJSON *next, *prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
int type; /* The type of the item, as above. */
char *valuestring; /* The item's string, if type==cJSON_String */
uint64 valueint; /* The item's number, if type==cJSON_Number */
double valuedouble; /* The item's number, if type==cJSON_Number */
int sign; /* sign of valueint, 1(unsigned), -1(signed) */
char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} cJSON;
所有函数围绕操作该结构体为导向组成的cJSON库,而json文件是由 “键/值”构成,值可以是数字、字符串、逻辑值(true/false)、数组(方括号[])、对象(花括号{})、null。
一个实例化的cJSON结构体就是可以表示一个 “键/值”对,其中除了包含 “键/值”信息外还包含指向下/上一个 “键/值”的指针,就好像双向链表一样,所以下文对 “键/值”对使用节点表述。
(1)读取解析
使用QFile
读取json文件所有内容到内存,然后使用cJSON_Parse
函数解析内容并返回root节点指针,如下代码。
QFile jsonFile(JSON_FILE);
if(! jsonFile.open(QIODevice::ReadOnly | QIODevice::Text))
return;
QByteArray jsonInfo = jsonFile.readAll();
cJSON *root = cJSON_Parse(jsonInfo.data());
if(!root) return;
(2)获取节点下子节点
接着上文,使用cJSON_GetArraySize
函数可获取root节点下面的子节点数;
- 使用
cJSON_GetArrayItem
函数可以获取子节点指针。
int subItemCount = cJSON_GetArraySize(root);
for(int i = 0;i < subItemCount;i ++)
{
cJSON *subItem = cJSON_GetArrayItem(root,i);
}
- 也可以使用
cJSON_GetObjectItem
函数通过子节点名(对象名)获取子节点指针。
cJSON *serumItem = cJSON_GetObjectItem(subItem,"serum");
cJSON *plasmaItem = cJSON_GetObjectItem(subItem,"plasma");
cJSON *wholeBloodItem = cJSON_GetObjectItem(subItem,"wholeBlood");
cJSON *urineItem = cJSON_GetObjectItem(subItem,"urine");
cJSON *qcItem = cJSON_GetObjectItem(subItem,"QC");
subItem是上面root节点下面的子节点,以上是获取该子节点下面的子节点。
(3)获取节点名
cJSON结构体中包含自身描述字符串,这里称为节点名。
serumItem->string;
(4)获取节点的值
serumItem->valuestring;
通过直接获取结构体成员变量,int、double类型都可以该方法获取。
(5)修改节点名
(6)修改节点值
(7)增加子节点
(8)删除子节点