使用cJSON解析未知键名与值类型的JSON的实现问题问询
cJSON实现未知类型目标键值统一转字符串方案
完全可以实现,cJSON内置了类型判断接口和通用序列化能力,不需要提前预知键A/B的对应值类型,数组场景也可以直接处理。
实现逻辑
- 第一步:先解析原始JSON,定位目标键
用cJSON_Parse解析原始JSON得到根节点后,先后查询键A和B的存在性,取存在的节点作为处理对象,都不存在可按业务逻辑返回空值。 - 第二步:按节点类型处理转字符串
- 字符串类型:直接拷贝节点的
valuestring成员即可,注意要深拷贝,避免cJSON节点释放后内存被回收 - 数值/布尔/空值类型:直接用cJSON提供的序列化方法转字符串
- 数组/对象类型:调用序列化方法直接得到原结构的JSON格式字符串,不需要手动遍历;如果有自定义格式要求,也可以自己遍历节点拼接。
- 字符串类型:直接拷贝节点的
示例代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "cJSON.h" char* get_target_val_str(const char* raw_json) { // 解析原始JSON cJSON* root = cJSON_Parse(raw_json); if (root == NULL) return strdup(""); // 定位目标键A/B cJSON* target = cJSON_GetObjectItemCaseSensitive(root, "A"); if (target == NULL) { target = cJSON_GetObjectItemCaseSensitive(root, "B"); } if (target == NULL) { cJSON_Delete(root); return strdup(""); } char* res = NULL; // 字符串类型直接拷贝值 if (cJSON_IsString(target)) { res = strdup(target->valuestring); } else { // 其他类型(数值、数组、对象、布尔等)统一序列化 // 无格式化输出省空间,需要带缩进格式化可替换为cJSON_Print res = cJSON_PrintUnformatted(target); } cJSON_Delete(root); return res; } // 调用示例 int main() { // 测试数组场景 const char* test_json = "{\"B\": [1, \"test\", true]}"; char* val = get_target_val_str(test_json); printf("转换结果:%s\n", val); // 输出:[1,"test",true] free(val); // 用完必须释放返回的字符串 return 0; }
自定义数组格式转换
如果需要把数组转成逗号分隔的纯值字符串而非标准JSON数组格式,可以手动遍历数组节点拼接,示例逻辑如下:
if (cJSON_IsArray(target)) { int arr_size = cJSON_GetArraySize(target); res = (char*)calloc(arr_size * 64, 1); // 按业务需要分配足够空间 for (int i = 0; i < arr_size; i++) { cJSON* elem = cJSON_GetArrayItem(target, i); char* elem_str = cJSON_PrintUnformatted(elem); if (i != 0) strcat(res, ","); strcat(res, elem_str); free(elem_str); } }
内容的提问来源于stack exchange,提问作者notAuser
相关产品推荐
相关产品推荐

