programerXiao

博客园 首页 新随笔 联系 订阅 管理

1.5 cJSON中的基本数据操作

  在上一节,我们着重介绍了cJSON中的一个很重要的数据结果cJSON类型,以及如何将C语言中的几种基本数据类型对应的变量转换为cJSON的结点类型,以及如何使用cJSON_CreateXXX系列的函数来创建与C语言的基础数据类型匹配的cJSON结点。以及如何使用cJSON的valuetype成员得到cJSON结点中所真正的存储的数据类型。然后还介绍了为什么cJSON中要引入引用类型的原因。(因为如果不是引用类型创建的cJSON结点,它里面的值的存储区是一个深拷贝,不会影响到传入的值的值;而对于引用类型就相当于数据域的空间本质就是指向的传入的那个变量的地址。也就是浅拷贝)。

  而在这一节,我们将重点说明如何对这些数据类型进行获取或类型判断的操作。这会用到cJSON_IsXXXX系列函数,以及当确定了具体的cJSON中所存储的真正的C的基本数据类型之后如何使用cJSON_GetXXX系列函数来取得cJSON结点里面的值。

1.5.1 使用cJSON_IsXXXX系列函数来判断cJSON结点的类型

//1.使用cJSON的cJSON_IsXXX系列函数判断cJSON Item结点的类型
///1.1 先创建一些不同类型的cJSON的Item结点
cJSON*numItem = cJSON_CreateNumber(3.1415);          //创建一个数字类型的Item
cJSON*strItem = cJSON_CreateString("Hello,World!");  //创建一个String类型的Item
float floatArray[4] = { 1.23f,2.34f,4.35f,5.34f };
cJSON*floatArrayItem = cJSON_CreateFloatArray(floatArray, 4);// 创建一个Float Array类型的Item
cJSON* trueItem = cJSON_CreateTrue();//创建一个bool类型的True的Item
cJSON* falseItem = cJSON_CreateFalse();//创建一个bool类型的False的Item
cJSON* nullItem = cJSON_CreateNull();//创建一个有效的但内部的cJSON内容为NULL的Item结点
cJSON* objectItem = cJSON_CreateObject();//创建一个cJSON的Object类型的Item结点(相当于这个结点还是一个cJSON对象)
cJSON* rawItem = cJSON_CreateRaw("{\"Name\":\"LBXXPointer\"}");//从一段原始JSON串创建一个JSON Item对象结点


///1.2 使用cJSON_IsXXX系列函数判断结点的类型是否符合预期
////1.2.1 使用cJSON_IsNumber判断当前结点是不是数字类型
cout << "numItem " << (cJSON_IsNumber(numItem)?"Is Number Item.":"Not Number Item.") << endl;
////1.2.2 使用cJSON_IsString判断当前结点是不是字符串类型
cout << "strItem " << (cJSON_IsString(strItem)?"Is String Item.":"Not String Item.") << endl;
////1.2.3 使用cJSON_IsArray来判断当前结点是不是数组类型(只要是数组都可以)
cout << "floatArrayItem " << (cJSON_IsArray(floatArrayItem) ? "Is Array Item." : "Not Array Item.") << endl;
////1.2.4 使用cJSON_IsBool()来判断当前结点是不是bool类型的结点
cout << "trueItem " << (cJSON_IsBool(trueItem) ? "Is bool Item." : "Not bool Item.") << endl;
cout << "falseItem " << (cJSON_IsBool(falseItem) ? "Is bool Item." : "Not bool Item.") << endl;
cout << "trueItem Value " << (cJSON_IsTrue(trueItem) ? "Is True Value." : "Not True Value.") << endl;
cout << "falseItem Value " << (cJSON_IsFalse(falseItem) ? "Is False Value." : "Not False Value.") << endl;

对cJSON_Is系列函数的总结如下表

函数名称 功能作用
cJSON_IsInvalid(const cJSON * const item) 判断当前的item结点中存储的数据的类型是不是非法的无效的类型(这用于判断cJSON结点的类型是否合法)
cJSON_IsFalse(const cJSON * const item) 判断当前item结点是不是cJSON_bool类型,如果是那么如果cJSON结点的值是False,那么此函数返回True
cJSON_IsTrue(const cJSON * const item) 判断当前item结点是不是cJSON_bool类型,如果是那么如果cJSON结点的值是True,那么此函数返回True
cJSON_IsBool(const cJSON * const item) 如果当前item结点的类型只要是bool类型则返回true
cJSON_IsNull(const cJSON * const item) 如果当前结点中存储的数据是空值,那么函数返回true
cJSON_IsNumber(const cJSON * const item) 如果当前结点中存储的数据本质是一个数字类型,那么函数返回true
cJSON_IsString(const cJSON * const item) 若当前cJSON结点中存储了一个C风格字符串,那么返回true
cJSON_IsArray(const cJSON * const item) 若当前cJSON中存储的数据是一个数组类型(不论是字符串数组还是数字数组),都返回True,此函数往往和cJSON_GetArraySize以及For循环来配合使用遍历里面的值。
cJSON_IsObject(const cJSON * const item) 若当前cJSON结点仍然是一个子JSON串对象,那么返回true
cJSON_IsRaw(const cJSON * const item) 若当前cJSON结点中存储了一段原始的cJSON字符串,那么返回true

1.5.2 使用cJSON_GetXXX系列函数来获取cJSON结点中所存储的对应的数据类型的值

  上一节所学习的cJSON_CreateXXX系列函数的本质就是将C语言的几乎所有的基础数据类型的变量都通过CreateXXX系列函数转换并拷贝为一个cJSON的Item结点(当然有深拷贝和浅拷贝[引用传递])两种方式。这本质上是将C语言的基础数据类型都转换为cJSON的结点类型进行管理。那么如果需要将cJSON的Item结点类型中存储的基本的C语言的数据类型的变量的值,那么就需要使用到cJSON_GetXXXX系列函数了。以下是对这一系列函数的使用和总结。

//1.使用cJSON的cJSON_IsXXX系列函数判断cJSON Item结点的类型
///1.1 先创建一些不同类型的cJSON的Item结点
cJSON*numItem = cJSON_CreateNumber(3.1415);          //创建一个数字类型的Item
cJSON*strItem = cJSON_CreateString("Hello,World!");  //创建一个String类型的Item
float floatArray[4] = { 1.23f,2.34f,4.35f,5.34f };
cJSON*floatArrayItem = cJSON_CreateFloatArray(floatArray, 4);// 创建一个Float Array类型的Item
cJSON* trueItem = cJSON_CreateTrue();//创建一个bool类型的True的Item
cJSON* falseItem = cJSON_CreateFalse();//创建一个bool类型的False的Item
cJSON* nullItem = cJSON_CreateNull();//创建一个有效的但内部的cJSON内容为NULL的Item结点
cJSON* objectItem = cJSON_CreateObject();//创建一个cJSON的Object类型的Item结点(相当于这个结点还是一个cJSON对象)
cJSON* rawItem = cJSON_CreateRaw("{\"Name\":\"LBXXPointer\"}");//从一段原始JSON串创建一个JSON Item对象结点

///1.3 使用cJSON_GetXXX系列函数来将CJSON的结点类型转换为原始的标准的C的基础数据类型,并且使用它
////1.3.1 假设我们知道numItem是数字类型(可以使用valueType成员判断,也可以使用前面的IsNumber判断),使用cJSON_GetNumberValue将JSON结点中存储的数字提取出来
double number = cJSON_GetNumberValue(numItem);
cout << "The NumerItem After GetNumberValue Is " << number << endl;
////1.3.2 使用cJSON_GetStringValue取出cJSON结点中字符串结点的字符串值
char*str = cJSON_GetStringValue(strItem);//这个str的内存空间不需要释放,这个内存空间实际上本质就是cJSON结点内部维护的,如果调用cJSON_Delete释放了strItem结点,那么这个str所执指向的空间也会被释放
cout << "The strItem After cJSON_GetStringValue Is " << str << endl;
////1.3.3 使用cJSON_GetArraySize获得数组Item中的元素个数,并配合cJSON_GetArrayItem取出Array中每一个下标的cJSON结点,然后使用GetNumberValue得到数组元素的值
cout << "floatArrayItem Is {";
int elemCount = cJSON_GetArraySize(floatArrayItem);
for (int i = 0; i < elemCount; ++i)
{
    cJSON* item = cJSON_GetArrayItem(floatArrayItem, i);
    //假设我们知道item类型就是数字类型
    double value = cJSON_GetNumberValue(item);
    cout << value << (i == elemCount - 1 ? "" : ",");
}
cout << "}" << endl;
////实际上对于数组类型的获取都可以采用上述逻辑,只不过数据的类型可能是String或者是其它类型而已,这个自行写逻辑特殊处理即可
    

对cJSON_GetXXX系列函数的总结

函数名称 函数的功能以及作用
(int) cJSON_GetArraySize(const cJSON *array) 假设确定了array是一个数组结点,那么此函数会返回这个数组中有多少个元素(array的类型可以是字符串数组,也可以是数字类型数组,还可以是其他类型的数组)
(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index) 此函数用于取出数组Item中指定index索引的数组元素的Item,这个Item本质也是一个cJSON结点,这个结点的值可以通过cJSON_Is系列函数判断,也可以通过valuetype进行判断后取得其中存储的值。如果函数失败,则返回NULL
(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string) 此函数用于从一个JSON上下文中获取一个名字叫做string的cJSON的子JSON对象。这个对象仍然是一个JSON子串。需要注意的是,这里的string的名字不区分大小写,假设有一个JSON对象叫做{"BaseInfo":{"Name":"LBXXPointer"}}那么向此函数传入baseinfo或者是BaseInfo都能获取到对应的JSON对象的子JSON串。
(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string) 此函数的主要功能和上面那个函数一样,但是此函数的string是严格区分大小写的,传入baseinfo就不可能得到有效的JSON对象的子JSON串上下文。除非严格输入BaseInfo才能成功获取到。
(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string) 此函数的作用是‌判断一个 JSON 对象中是否包含指定名称(Key)的字段‌,而不是判断该字段的值里面是否包含子 JSON 对象。相当于这个函数就是用来判断一下指定的JSON对象里面有没有对应叫做string的键。
(const char *) cJSON_GetErrorPtr(void) 这个函数用于获取解析JSON出错的地址的位置,往往把这个函数和cJSON_Parse系列函数配合来使用
(char *) cJSON_GetStringValue(const cJSON * const item) 假设item对象中存储的是字符串,那么通过此函数传入item对象,就可以得到里面的C风格字符串(这个char*是和item中存储char*的内存块绑定的)
posted on 2026-08-11 20:45  蜡笔小新Pointer  阅读(0)  评论(0)    收藏  举报