const char test_data3[] = " {\"method\":\"thing.service.property.set\",\"id\":\"1352110764\",\"params\":{\"Switch_2\":0,\"Switch_1\":0,\"data2\":456,\"array2\":[3,4],\"data1\":123,\"array1\":[1,2],\"text\":\" Switch_1:0 \"},\"version\":\"1.0.0\"} "; 使用C89标准,旧版本cJSON库解析嵌套字段的JSON字符串,预留提示位,方便扩展新数据
时间: 2025-06-19 22:56:52 浏览: 8
### 解析嵌套字段的 JSON 字符串并预留扩展提示位
以下是一个使用 C89 标准和旧版本 cJSON 库解析包含嵌套字段(如 `params` 对象)的 JSON 字符串的完整示例。同时,代码中为未来扩展新数据预留了提示位。
#### 示例代码
```c
#include <stdio.h>
#include <string.h>
#include "cJSON.h"
#define MAX_STRING_LENGTH 256
void parse_json(const char* json_string, ParsedData* parsed_data) {
cJSON* root = cJSON_Parse(json_string);
if (!root) {
fprintf(stderr, "Error before: [%s]\n", cJSON_GetErrorPtr());
return;
}
// 提取 method 字段
cJSON* method_item = cJSON_GetObjectItem(root, "method");
if (method_item && method_item->type == cJSON_String) { // 检查是否为字符串类型[^1]
strncpy(parsed_data->method, method_item->valuestring, sizeof(parsed_data->method) - 1);
} else {
parsed_data->method[0] = '\0'; // 如果字段不存在或类型不匹配,设置为空字符串
}
// 提取 id 字段
cJSON* id_item = cJSON_GetObjectItem(root, "id");
if (id_item && id_item->type == cJSON_String) { // 检查是否为字符串类型
strncpy(parsed_data->id, id_item->valuestring, sizeof(parsed_data->id) - 1);
} else {
parsed_data->id[0] = '\0'; // 如果字段不存在或类型不匹配,设置为空字符串
}
// 提取 params 对象
cJSON* params_item = cJSON_GetObjectItem(root, "params");
if (params_item && params_item->type == cJSON_Object) { // 检查是否为对象类型
// 提取 Switch_1 字段
cJSON* switch_1_item = cJSON_GetObjectItem(params_item, "Switch_1");
if (switch_1_item && switch_1_item->type == cJSON_Number) { // 检查是否为数字类型[^1]
parsed_data->Switch_1 = switch_1_item->valueint;
} else {
parsed_data->Switch_1 = 0; // 如果字段不存在或类型不匹配,设置默认值
}
// 提取 Switch_2 字段
cJSON* switch_2_item = cJSON_GetObjectItem(params_item, "Switch_2");
if (switch_2_item && switch_2_item->type == cJSON_Number) { // 检查是否为数字类型
parsed_data->Switch_2 = switch_2_item->valueint;
} else {
parsed_data->Switch_2 = 0; // 如果字段不存在或类型不匹配,设置默认值
}
// 提取 data1 字段
cJSON* data1_item = cJSON_GetObjectItem(params_item, "data1");
if (data1_item && data1_item->type == cJSON_Number) { // 检查是否为数字类型[^1]
parsed_data->data1 = data1_item->valueint;
} else {
parsed_data->data1 = 0; // 如果字段不存在或类型不匹配,设置默认值
}
// 提取 data2 字段
cJSON* data2_item = cJSON_GetObjectItem(params_item, "data2");
if (data2_item && data2_item->type == cJSON_Number) { // 检查是否为数字类型[^1]
parsed_data->data2 = data2_item->valueint;
} else {
parsed_data->data2 = 0; // 如果字段不存在或类型不匹配,设置默认值
}
// 提取 array1 数组
cJSON* array1_item = cJSON_GetObjectItem(params_item, "array1");
if (array1_item && array1_item->type == cJSON_Array) { // 检查是否为数组类型
int size = cJSON_GetArraySize(array1_item);
for (int i = 0; i < size && i < 10; i++) {
cJSON* item = cJSON_GetArrayItem(array1_item, i);
if (item && item->type == cJSON_Number) { // 检查数组元素是否为数字类型
parsed_data->array1[i] = item->valueint;
} else {
parsed_data->array1[i] = 0; // 如果元素类型不匹配,设置默认值
}
}
}
// 提取 array2 数组
cJSON* array2_item = cJSON_GetObjectItem(params_item, "array2");
if (array2_item && array2_item->type == cJSON_Array) { // 检查是否为数组类型
int size = cJSON_GetArraySize(array2_item);
for (int i = 0; i < size && i < 10; i++) {
cJSON* item = cJSON_GetArrayItem(array2_item, i);
if (item && item->type == cJSON_Number) { // 检查数组元素是否为数字类型
parsed_data->array2[i] = item->valueint;
} else {
parsed_data->array2[i] = 0; // 如果元素类型不匹配,设置默认值
}
}
}
// 提取 text 字段
cJSON* text_item = cJSON_GetObjectItem(params_item, "text");
if (text_item && text_item->type == cJSON_String) { // 检查是否为字符串类型[^1]
strncpy(parsed_data->text, text_item->valuestring, sizeof(parsed_data->text) - 1);
} else {
parsed_data->text[0] = '\0'; // 如果字段不存在或类型不匹配,设置为空字符串
}
// 预留扩展提示位
cJSON* reserved_field = cJSON_GetObjectItem(params_item, "reserved");
if (reserved_field) {
printf("Reserved field detected: %s\n", reserved_field->valuestring ? reserved_field->valuestring : "null");
}
}
// 提取 version 字段
cJSON* version_item = cJSON_GetObjectItem(root, "version");
if (version_item && version_item->type == cJSON_String) { // 检查是否为字符串类型
strncpy(parsed_data->version, version_item->valuestring, sizeof(parsed_data->version) - 1);
} else {
parsed_data->version[0] = '\0'; // 如果字段不存在或类型不匹配,设置为空字符串
}
cJSON_Delete(root);
}
```
#### 说明
- 在旧版本 cJSON 中,通过直接检查 `cJSON` 对象的 `type` 字段来替代现代版本中的 `cJSON_IsString`、`cJSON_IsNumber` 和 `cJSON_IsObject` 函数。
- 为每个字段添加了默认值处理逻辑,确保在字段缺失或类型不匹配时不会导致程序崩溃。
- 添加了预留扩展提示位,用于检测未来的扩展字段。
---
###
阅读全文
相关推荐


















