C++解析和构建json【cjson使用手册】
- 一、cjson下载
- 二、cjson工程使用
- 2.1 静态库使用
- 2.1 源码使用(推荐)
- 三、cjson详解
- 3.1 解析json字符串
- 3.1.1 解析对象
- 3.1.2 解析数组:方法一(获取列表数量然后按照位置获取)
- 3.1.2 解析数组:方法二(使用foreach遍历)
- 3.1.3 解析对象包含数组
- 3.1.4 解析数组对象
- 3.2 json结构体构建
- 3.2.1 构建对象
- 3.2.2 构建数组
- 3.2.3 构建对象中包含数组
- 3.2.4 构建数组中包含对象
- 3.3 json类型判断
- 1. `cJSON_IsInvalid`
- 2. `cJSON_IsFalse`
- 3. `cJSON_IsTrue`
- 4. `cJSON_IsBool`
- 5. `cJSON_IsNull`
- 6. `cJSON_IsNumber`
- 7. `cJSON_IsString`
- 8. `cJSON_IsArray`
- 9. `cJSON_IsObject`
- 10. `cJSON_IsRaw`
- 四、源码地址
json_1">一、cjson下载
-
国外:github下载
https://github.com/DaveGamble/cJSON
-
国内:gicode下载
https://gitcode.com/gh_mirrors/cj/cJSON/overview
json_10">二、cjson工程使用
2.1 静态库使用
将cjson作为静态库使用。
cmake_minimum_required( VERSION 3.10 )
project(cjson)add_library(${PROJECT_NAME} cjson.c cjson.h)install(TARGETS ${PROJECT_NAME} DESTINATION lib)
install(FILES ${PROJECT_SOURCE_DIR}/cjson.h DESTINATION include)
使用qt编译。
- 2.使用cjson静态库
将编译的cjson.lib和cjson.h放在项目中的depend/cjson/中
depend/cjson/lib/cjson.lib
depend/cjson/include/cjson.h
项目中指定库文件和头文件。分别任上面两个目录就可以了。
2.1 源码使用(推荐)
源码使用,比较简单。
直接将cjson.c和cjson.h放在源文件中一起编译就可以了。
json_34">三、cjson详解
json_35">3.1 解析json字符串
json解析的最终结果只有三种1. 字符串类型。2.整数。3.float。
整个字符串解析的关键函数为cJSON_Parse
公共函数说明
文件读取,传递文件名称获取文件内容。(因为json文件中的双引号比较麻烦输入,所以我直接将测试内容放在文件中读取这样比较方便。)
string ReadFile(string filePath){ifstream ifs(filePath);if(!ifs.is_open()){return "";}std::string line;std::string content;while (getline(ifs, line)) { // 逐行读取文件内容content+=line;}ifs.close(); // 关闭文件return content;
}
因为创建的对象不知道什么时候释放,因此我使用智能指针的方式,等到他不使用的时候自动释放。
struct cJSON_Deleter {void operator()(cJSON* json) const {cJSON_free(json);}
};
3.1.1 解析对象
样例一:
json">{"name":"三雷科技","age":100,"hight":124.5
}
解析代码如下:
void parse_object1(){string content = ReadFile("data/object1.txt");if(content.empty()){return;}std::unique_ptr<cJSON,cJSON_Deleter> json_data(cJSON_Parse(content.c_str()));if(json_data == nullptr){cout <<"解析失败!";}cJSON *json_name = cJSON_GetObjectItem(json_data.get(),"name");cJSON *json_age = cJSON_GetObjectItem(json_data.get(),"age");cJSON *json_hight = cJSON_GetObjectItem(json_data.get(),"hight");string name = json_name->valuestring;int age = json_age->valueint;double hight = json_hight->valuedouble;cout <<"name:"<<name<<endl;cout <<"age:"<<age<<endl;cout <<"hight:"<<hight<<endl;
}
json_data:为获取的json对象。
cJSON_GetObjectItem从对象中获取对象中的属性内容。根据关键词进行获取。
拿到该关键的json对象item以后再使用valuestring\valueint\valuedouble获取对应类型的值。
3.1.2 解析数组:方法一(获取列表数量然后按照位置获取)
样例一:
json">["apple","banana","Orange","watermelon"]
想获取列表的长度,然后按照位置进行获取。
cJSON_GetArraySize:该函数用于获取 JSON 数组的大小(即数组中的元素数量)。
cJSON_GetArrayItem:该函数用于获取 JSON 数组中的某个特定索引处的元素。
void parse_array1(){string content = ReadFile("data/array1.txt");if(content.empty()){cout<<"读取内容失败";return;}std::unique_ptr<cJSON,cJSON_Deleter> json_data(cJSON_Parse(content.c_str()));int len = cJSON_GetArraySize(json_data.get());for(int i = 0 ;i < len ; i++){cJSON *item = cJSON_GetArrayItem(json_data.get(),i);if(item){cout <<"item:"<<item->valuestring<<endl;}}
}
3.1.2 解析数组:方法二(使用foreach遍历)
样例一:
json">["apple","banana","Orange","watermelon"]
cJSON_ArrayForEach:遍历 cJSON 数组: cJSON_ArrayForEach 可以轻松遍历 cJSON 数组中的每一个元素,省去了手动获取数组大小和逐个索引访问元素的麻烦。
void parse_array2(){string content = ReadFile("data/array1.txt");if(content.empty()){cout<<"读取内容失败";return;}std::unique_ptr<cJSON,cJSON_Deleter> json_data(cJSON_Parse(content.c_str()));cJSON* item = nullptr;cJSON_ArrayForEach(item, json_data.get()) {if (cJSON_IsString(item)) {std::cout << "item: " << item->valuestring<< std::endl;}}
}
3.1.3 解析对象包含数组
案例:
json">{"fruit":["apple","banana","Orange","watermelon"],"unit":["one","two","three"]
}
需要分布解析,先解析对象然后在解析每个数组,需要一个一个的解析。
void parse_object_array(){string content = ReadFile("data/object_array.txt");if(content.empty()){cout<<"读取内容失败";return;}std::unique_ptr<cJSON,cJSON_Deleter> json_data(cJSON_Parse(content.c_str()));cJSON *json_fruit_array = cJSON_GetObjectItem(json_data.get(),"fruit");cJSON* item = nullptr;cJSON_ArrayForEach(item, json_fruit_array) {if (cJSON_IsString(item)) {std::cout << "fruit item: " << item->valuestring<< std::endl;}}cJSON *json_unit_array = cJSON_GetObjectItem(json_data.get(),"unit");cJSON_ArrayForEach(item, json_unit_array) {if (cJSON_IsString(item)) {std::cout << "unit item: " << item->valuestring<< std::endl;}}
}
运行结果
3.1.4 解析数组对象
案例 array_object.txt
json">{"students": [{"name": "Alice", "age": 21},{"name": "Bob", "age": 22},{"name": "Charlie", "age": 23}]
}
void parse_array_object(){string content = ReadFile("data/array_object.txt");if(content.empty()){cout<<"读取内容失败";return;}std::unique_ptr<cJSON,cJSON_Deleter> json_data(cJSON_Parse(content.c_str()));// 先获取students的jsoncJSON *json_student_array = cJSON_GetObjectItem(json_data.get(),"students");if(cJSON_IsNull( json_student_array)){cout<<"students 解析失败";return ;}if(cJSON_IsArray(json_student_array)){cJSON* item = nullptr;cJSON_ArrayForEach(item,json_student_array){cJSON* json_item_name = cJSON_GetObjectItem(item,"name");cJSON* json_item_age = cJSON_GetObjectItem(item,"age");if(json_item_name){std::cout <<"name:"<<json_item_name->valuestring;}if(json_item_age){std::cout <<",age:"<<json_item_age->valueint;}std::cout << std::endl;}}
}
运行结果
json_226">3.2 json结构体构建
构建好的json结构体可以通过cJSON_Print获取json结构对应的字符串。
3.2.1 构建对象
3.2.2 构建数组
- 构建整形数组
cJSON_CreateIntArray:
void CreateIntArray(){int num[] = {10,4,5,6,1};cJSON *json_int_array = cJSON_CreateIntArray(num,sizeof(num));std::cout << cJSON_Print(json_int_array)<<std::endl;;cJSON_Delete(json_int_array );
}
- 构建float数组
cJSON_CreateFloatArray:
void CreateFloatArray(){float num[] = {10.1,4.2,5.3,6.4,1.5};cJSON *json_float_array = cJSON_CreateFloatArray(num,sizeof(num));std::cout << cJSON_Print(json_float_array)<<std::endl;;cJSON_Delete(json_float_array );
}
- 构建Double数组
cJSON_CreateDoubleArray:
void CreateDoubleArray(){double num[] = {10.1,4.2,5.3,6.4,1.5};cJSON *json_float_array = cJSON_CreateDoubleArray(num,sizeof(num));std::cout << cJSON_Print(json_float_array)<<std::endl;;cJSON_Delete(json_float_array );
}
- 构建字符串数组
cJSON_CreateStringArray:
void CreateDoubleArray(){const char *string[] = { "Hello", "World", "I", "Am", "Programmer"};cJSON *json_string_array = cJSON_CreateDoubleArray(string,sizeof(string)/sizeof(string[0]));std::cout << cJSON_Print(json_string_array)<<std::endl;;cJSON_Delete(json_string_array);
}
- 构建任意类型数组
void CreateArray(){cJSON *cjson_array = cJSON_CreateArray();cJSON *cjson_number = cJSON_CreateNumber(10);cJSON *cjson_bool = cJSON_CreateBool(false);cJSON *cjson_string = cJSON_CreateString("name");cJSON_AddItemToArray(cjson_array,cjson_number);cJSON_AddItemToArray(cjson_array,cjson_bool );cJSON_AddItemToArray(cjson_array,cjson_string );std::cout <<cJSON_Print(json_array)<<std::endl;cJSON_Delete(cjson_array);
}
3.2.3 构建对象中包含数组
void CreateObejectArray(){std::unique_ptr<cJSON,cJSON_Deleter> json_data(cJSON_CreateObject());const char *string[] = { "Hello", "World", "I", "Am", "Programmer"};cJSON *json_string_array = cJSON_CreateStringArray(string,sizeof(string)/sizeof(string[0]));double num[] = {10.1,4.2,5.3,6.4,1.5};cJSON *json_float_array = cJSON_CreateDoubleArray(num,sizeof(num)/sizeof (double));cJSON_AddItemToObject(json_data.get(),"word",json_string_array );cJSON_AddItemToObject(json_data.get(),"number",json_float_array );std::cout <<cJSON_Print(json_data.get())<<std::endl;
}
cJSON_AddItemToObeject:创建一个item添加到一个对象中,参数为:
json_object:json对象
string : 关键词
json_item:对象的值
3.2.4 构建数组中包含对象
struct Student{Student(std::string name ,int age ,std::string sex){this->name = name;this->age = age;this->sex = sex;}std::string name;int age;std::string sex;
};
void CreateArrayObeject(){std::unique_ptr<cJSON,cJSON_Deleter> json_data(cJSON_CreateArray());std::vector<Student> vstu;Student stu1("zhangsan",10,"nan");Student stu2("lisi",12,"nan");Student stu3("wangwu",13,"nv");vstu.push_back(stu1);vstu.push_back(stu2);vstu.push_back(stu3);for(auto stu :vstu){cJSON *item = cJSON_CreateObject();cJSON_AddItemToObject(item ,"name",cJSON_CreateString(stu.name.c_str()));cJSON_AddItemToObject(item ,"age",cJSON_CreateNumber(stu.age));cJSON_AddItemToObject(item ,"sex",cJSON_CreateString(stu.sex.c_str()));cJSON_AddItemToArray(json_data.get(),item);}std::cout <<cJSON_Print(json_data.get())<<std::endl;
}
运行结果:
json_345">3.3 json类型判断
cJSON
库提供了一组宏,用于检查 cJSON
对象的类型。这些宏使得在处理 JSON 数据时,可以轻松地判断 JSON 对象的类型,并根据类型进行相应的处理。以下是这些宏的详细说明:
1. cJSON_IsInvalid
功能: 判断 cJSON
对象是否是无效的(类型为 cJSON_Invalid
)。
使用场景: 在处理 JSON 解析结果时,用于检查对象是否无效或未初始化。
2. cJSON_IsFalse
功能: 判断 cJSON
对象是否为布尔值 false
(即类型为 cJSON_False
)。
使用场景: 用于检测 JSON 布尔值 false
。
3. cJSON_IsTrue
功能: 判断 cJSON
对象是否为布尔值 true
(即类型为 cJSON_True
)。
使用场景: 用于检测 JSON 布尔值 true
。
4. cJSON_IsBool
功能: 判断 cJSON
对象是否为布尔类型(即类型为 cJSON_True
或 cJSON_False
)。
使用场景: 用于检测 JSON 布尔类型的值,不论是 true
还是 false
。
5. cJSON_IsNull
功能: 判断 cJSON
对象是否为 null
(即类型为 cJSON_NULL
)。
使用场景: 用于检测 JSON 中的 null
值。
6. cJSON_IsNumber
功能: 判断 cJSON
对象是否为数字(即类型为 cJSON_Number
)。
使用场景: 用于检测 JSON 中的数字类型。
7. cJSON_IsString
功能: 判断 cJSON
对象是否为字符串(即类型为 cJSON_String
)。
使用场景: 用于检测 JSON 中的字符串类型。
8. cJSON_IsArray
功能: 判断 cJSON
对象是否为数组(即类型为 cJSON_Array
)。
使用场景: 用于检测 JSON 中的数组类型。
9. cJSON_IsObject
功能: 判断 cJSON
对象是否为对象(即类型为 cJSON_Object
)。
使用场景: 用于检测 JSON 中的对象类型。
10. cJSON_IsRaw
功能: 判断 cJSON
对象是否为原始未处理的 JSON 数据(即类型为 cJSON_Raw
)。
使用场景: 用于检测未被处理的原始 JSON 数据,通常用在需要处理 JSON 内嵌代码或未解析的文本时。
四、源码地址
git源码
https://gitcode.net/arv002/qt/-/tree/master/c%2B%2B/cjson
csdn源码
https://download.csdn.net/download/arv002/89633210