解析cJSON:如何准确读取和判断数据类型**
在C语言中处理JSON数据,cJSON无疑是一个非常流行且轻量级的库,它将JSON数据解析成C语言中的数据结构,使得开发者可以方便地操作这些数据,正确地读取和判断JSON中元素的数据类型,是使用cJSON进行数据解析的关键步骤,本文将详细介绍如何使用cJSON提供的API来准确读取和判断数据类型。
cJSON的核心数据结构与类型概念
我们需要了解cJSON的基本组织方式和数据类型表示。
- cJSON结构体:cJSON库的核心是一个
cJSON结构体,每个JSON对象(Object)、数组(Array)、字符串(String)、数字(Number)等都对应一个cJSON结构体实例。 - 数据类型枚举:
cJSON结构体中有一个重要的成员type,它是一个枚举类型cJSON_Type,定义了所有可能的数据类型:typedef enum { cJSON_Invalid = -1, // 无效类型 cJSON_False = 0, // 布尔值 false cJSON_True = 1, // 布尔值 true cJSON_NULL = 2, // null 值 cJSON_Number = 3, // 数字 (整数或浮点数) cJSON_String = 4, // 字符串 cJSON_Array = 5, // 数组 cJSON_Object = 6, // 对象 cJSON_Raw = 7 // 原始JSON字符串 (不常用,通常用于特殊优化) } cJSON_Type;
判断数据类型的主要方法
cJSON提供了多种方法来判断和获取数据类型,最常用的是通过检查type成员以及使用专门的查询函数。
直接检查 type 成员
这是最底层也是最直接的方法,通过访问cJSON结构体的type成员,我们可以精确地知道它所代表的JSON数据类型。
#include <stdio.h>
#include <cJSON.h>
void check_type_by_direct(const cJSON *item) {
if (item == NULL) {
printf("Item is NULL\n");
return;
}
switch (item->type) {
case cJSON_False:
printf("Type: Boolean (false)\n");
break;
case cJSON_True:
printf("Type: Boolean (true)\n");
break;
case cJSON_NULL:
printf("Type: NULL\n");
break;
case cJSON_Number:
printf("Type: Number\n");
// 进一步判断是整数还是浮点数(见下文)
break;
case cJSON_String:
printf("Type: String\n");
break;
case cJSON_Array:
printf("Type: Array\n");
break;
case cJSON_Object:
printf("Type: Object\n");
break;
case cJSON_Raw:
printf("Type: Raw\n");
break;
default:
printf("Type: Unknown\n");
break;
}
}
使用便捷的查询函数
为了简化操作,cJSON提供了一系列以cJSON_Is开头的宏或函数,它们内部会检查type成员并返回布尔值,使代码更具可读性。
cJSON_IsInvalid(item):检查是否为无效类型。cJSON_IsFalse(item):检查是否为布尔值false。cJSON_IsTrue(item):检查是否为布尔值true。cJSON_IsNull(item):检查是否为NULL。cJSON_IsBool(item):检查是否为布尔值(true或false)。cJSON_IsNumber(item):检查是否为数字。cJSON_IsString(item):检查是否为字符串。cJSON_IsArray(item):检查是否为数组。cJSON_IsObject(item):检查是否为对象。cJSON_IsRaw(item):检查是否为原始JSON字符串。
示例:
#include <stdio.h>
#include <cJSON.h>
void check_type_by_convenience(const cJSON *item) {
if (item == NULL) {
printf("Item is NULL\n");
return;
}
if (cJSON_IsNumber(item)) {
printf("Type: Number\n");
} else if (cJSON_IsString(item)) {
printf("Type: String\n");
} else if (cJSON_IsBool(item)) {
printf("Type: Boolean (%s)\n", cJSON_IsTrue(item) ? "true" : "false");
} else if (cJSON_IsNull(item)) {
printf("Type: NULL\n");
} else if (cJSON_IsArray(item)) {
printf("Type: Array\n");
} else if (cJSON_IsObject(item)) {
printf("Type: Object\n");
} else {
printf("Type: Unknown or Invalid\n");
}
}
获取数据类型对应的具体值
判断了数据类型后,我们需要获取其对应的值,cJSON为每种类型提供了相应的获取函数。
布尔值 (Boolean)
cJSON_IsTrue(item):如果item为布尔值true,返回非零;否则返回0。cJSON_IsFalse(item):如果item为布尔值false,返回非零;否则返回0。- 注意:cJSON中布尔值是用
cJSON_True(值为1) 和cJSON_False(值为0) 这两个常量表示的,可以直接比较。
数字 (Number)
cJSON的数字类型可能是整数也可能是浮点数,它内部使用double类型来存储所有数字。
cJSON_GetNumberValue(item):获取数字值,返回double类型。- 如果JSON中是整数,返回的
double值可以安全地转换为整数(如果数值范围在int或long范围内)。 - 如果JSON中是浮点数,返回的就是浮点数。
- 如果JSON中是整数,返回的
如何区分整数还是浮点数?
cJSON本身不直接区分数字是整数还是浮点数,它只存储为double,你需要根据数字的值或者JSON原始字符串的格式来判断,如果cJSON_GetNumberValue(item)返回的值的小数部分为0,并且数值在整数范围内,那么可以认为它是一个整数。
cJSON *number_item = cJSON_GetObjectItemCaseSensitive(root, "age");
if (cJSON_IsNumber(number_item)) {
double num_val = cJSON_GetNumberValue(number_item);
printf("Number value: %f\n", num_val);
// 假设我们知道age应该是整数
int age = (int)num_val; // 注意:这里可能有精度丢失风险,如果num_val很大
printf("Age (as int): %d\n", age);
}
字符串 (String)
cJSON_GetStringValue(item):获取字符串值,返回const char*指针,如果item不是字符串类型或为NULL,返回NULL。cJSON_IsString(item):先判断是否为字符串类型。
cJSON *name_item = cJSON_GetObjectItemCaseSensitive(root, "name");
if (cJSON_IsString(name_item)) {
const char *name = cJSON_GetStringValue(name_item);
printf("Name: %s\n", name ? name : "(null)");
}
NULL值
cJSON_IsNull(item):检查是否为NULL值,没有获取函数,因为NULL值本身没有内容。
数组 (Array) 和对象 (Object)
对于数组(Array)和对象(Object),我们通常不直接获取一个“值”,而是遍历其元素或成员。
-
数组遍历:
cJSON_GetArraySize(array_item):获取数组元素个数。cJSON_GetArrayItem(array_item, index):获取指定索引的元素(cJSON*类型)。cJSON_ArrayForEach(iterable_element, array_item):宏,用于遍历数组中的每个元素。
-
对象遍历:
cJSON_GetObjectItemCaseSensitive(object_item, key):根据键(区分大小写)获取对应的值(cJSON*类型)。cJSON_GetObjectItem(object_item, key):根据键(不区分大小写)获取对应的值(cJSON*类型)。cJSON_GetArraySize(object_item):获取对象的成员个数(因为对象内部实现也是数组)。cJSON_GetArrayItem(object_item, index):获取对象中第index个成员(键值对中的值部分)。cJSON_ObjectForEach(iterable_element, object_item):宏,用于遍历对象中的每个成员(iterable_element是当前成员的cJSON*,
抖音足球直播
抖音足球直播
企鹅直播
企鹅直播
足球直播
爱奇艺直播
爱奇艺足球直播
足球直播
足球直播
iqiyi直播
足球直播
足球直播
QQ足球直播
QQ足球直播
足球直播
足球直播
QQ足球直播
QQ足球直播
足球直播
足球直播
快连
快连
快连
快连下载
快连
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
新浪足球直播
新浪足球直播
足球直播
足球直播
有道翻译
有道翻译
有道翻译
有道翻译
wps
wps
wps
wps
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
新浪足球直播
新浪足球直播
足球直播
足球直播



还没有评论,来说两句吧...