一、JSON简介
-
JSON 是一种纯字符串形式的数据,它本身不提供任何方法(函数),非常适合在网络中进行传输。
-
它具有结构简单、易读、解析快的特点。
-
广泛用于web开发中前后端交换数据、配置文件
二、JSON语法规则
1.语法格式
- 所有 JSON 数据需要包裹在一个花括号
{}
中 - 数据由若干键/值对组成,键不能重复
- 不同的键/值对之间使用逗号
,
分隔,最后一个不用键
表示数据的名称,字符串的形式
- 冒号
:
- 值
value
{
"name":"json",
"age":getage(),
"sex":"man"
}
2.数据结构
类型 | 说明 |
---|---|
String | 值是字符串,用双引号定义,可以使用转义符号 |
Number | 值是整数、浮点数、科学计数法 |
Boolean | 值是true和false |
Null | 空值,无具体值 |
Array | 数组,用[] 包裹。值可以是任何类型 |
Object | 对象,用{} 包裹。一个对象中可以包含零个或多个键/值对 值可以是任何类型 |
3.例子
- 字符串类型(String)
{
"name": "John",
"city": "New York"
}
- 数字类型(Number)
{
"age": 25,
"salary": 50000.50,
"discount": 1.5e-3
}
- 布尔类型(Boolean)
{
"isMarried": true,
"hasChildren": false
}
- 空值类型(Null)
{
"username": null,
"avatar": null
}
- 数组类型(Array)
{
"fruits": [
"apple",
"banana",
[14, 3.14, true],
{"lan1": "java", "lan2": "json"},
null
]
}
- 对象类型(Object)
{
"profile": {
"name": "Alice",
"age": 30,
"address": {
"street": "123 street",
"city": "nanjing",
"state": "private"
}
}
}
三、解析
这里以c语言简单演示,使用cjson
库
1.cJSON库基本用法
- 头文件
cJSON.h
- 解析JSON字符串
-
使用函数
cJSON_Parse
将JSON字符串转换为cJSON对象。 -
该函数返回一个指向 root cJSON 对象的指针。如果解析失败,则函数返回NULL。
cJSON *root = cJSON_Parse(json_string);
if (root == NULL) {
printf("Error: [%s]\n", cJSON_GetErrorPtr());
return 1;
}
- 遍历JSON对象
cJSON_GetObjectItemCaseSensitive
函数按名称访问 cJSON 对象的属性
{
"name": "Alice",
"age": 30,
"is_student": true
}
获取和打印JSON对象的属性
cJSON *name = cJSON_GetObjectItemCaseSensitive(root, "name");
printf("Name: %s\n", name->valuestring);
cJSON *age = cJSON_GetObjectItemCaseSensitive(root, "age");
printf("Age: %d\n", age->valueint);
cJSON *is_student = cJSON_GetObjectItemCaseSensitive(root, "is_student");
printf("Is Student: %d\n", is_student->valueint);
- 遍历JSON数组
可以使用 cJSON_ArrayForEach
宏遍历 JSON 数组中的元素
[
"apple",
"orange",
"banana"
]
使用以下代码打印数组元素
cJSON *array = cJSON_Parse(json_array_string);
cJSON *item = NULL;
cJSON_ArrayForEach(item, array) {
printf("%s\n", item->valuestring);
}
- 创建JSON对象
-
cJSON_CreateObject()
函数来创建新的空的 cJSON 对象。 -
cJSON_AddItemToObject
函数向该对象添加属性。
cJSON *new_obj = cJSON_CreateObject();
cJSON_AddStringToObject(new_obj, "name", "Alice");
cJSON_AddNumberToObject(new_obj, "age", 30);
- 序列化JSON
使用函数 cJSON_Print
可以将 cJSON 对象转换为 JSON 字符串输出,便于数据的传输和解析
char *json_str = cJSON_Print(root);
printf("%s\n", json_str);
free(json_str);
- 释放内存
在cJSON_Delete()
函数删除 cJSON 对象并释放其内存
cJSON_Delete(root);
2.案例
- cmake
cmake_minimum_required(VERSION 3.24)
project(untitled1 C)
set(CMAKE_C_STANDARD 11)
# 添加 cJSON 库
add_library(cjson STATIC cJSON.c cJSON.h)
# 链接 cJSON 库到主程序
add_executable(untitled1 main.c)
target_link_libraries(untitled1 cjson)
- 使用cjson
#include <stdio.h>
#include "cJSON.h"
int main() {
// 定义一个包含 JSON 字符串的变量
const char *jsonString = "{\n"
" \"Name\": \"解析json\",\n"
" \"Use\": \"cjson\",\n"
" \"Array\": [\n"
" \"json语法\",\n"
" \"json数据类型\",\n"
" \"json解析\"\n"
" ]\n"
"}";
// 解析 JSON 字符串为 cJSON 对象
cJSON *root = cJSON_Parse(jsonString);
if (root == NULL) {
printf("Error: [%s]\n", cJSON_GetErrorPtr());
return 1;
}
// 序列化json
char *json = cJSON_Print(root);
printf("序列化的json:\n%s\n", json);
// 获取 JSON 的属性值
cJSON *name = cJSON_GetObjectItemCaseSensitive(root, "Name");
cJSON *use = cJSON_GetObjectItemCaseSensitive(root, "Use");
cJSON *array = cJSON_GetObjectItemCaseSensitive(root, "Array");
// 打印 JSON 对象的属性值
printf("name: %s\n", name->valuestring);
printf("use: %s\n", use->valuestring);
// 打印数组
cJSON *item = NULL;
cJSON_ArrayForEach(item, array) {
printf("array: %s\n", item->valuestring);
}
// 释放 cJSON 对象的内存
cJSON_Delete(root);
return 0;
}
- 运行结果