JSON 完全指南:从语法到项目实战

引言

在现代软件开发中,数据交换无处不在------前端和后端通信、服务之间调用、配置文件读写、日志记录......这些场景都需要一种轻量、通用、易读的数据格式。

JSON (JavaScript Object Notation)就是目前最流行的选择。它诞生于 2001 年,原本是 JavaScript 的一个子集,但因为足够简单,很快被所有主流语言支持,成为事实上的数据交换标准

本文不深挖理论,聚焦于项目实战:JSON 长什么样、怎么写、在 C/C++ 项目中怎么用。

第一部分:JSON 是什么

一、一句话定义

JSON 是一种用文本表示结构化数据的格式。它只有两种结构:

  • 对象{ "key": value, ... } --- 键值对集合

  • 数组[ value, value, ... ] --- 有序值列表

二、一个完整的例子

复制代码
{
    "name": "张三",
    "age": 25,
    "isStudent": false,
    "hobbies": ["读书", "编程", "跑步"],
    "address": {
        "city": "北京",
        "district": "海淀区"
    },
    "phone": null
}

就这么简单。上面这段 JSON 描述了一个人的信息,任何语言的程序员都能看懂。


第二部分:JSON 的六种数据类型

完整示例:各种类型混合

复制代码
{
    "string": "文本",
    "number": 42,
    "float": 3.14,
    "bool": true,
    "null_value": null,
    "array": [1, "two", false, null],
    "object": {
        "nested": {
            "deep": "可以一直嵌套"
        }
    }
}

第三部分:JSON 的语法规则

一、必须遵守的规则

规则 正确 错误
键必须用双引号 {"name": "张三"} {name: "张三"}
字符串必须用双引号 "hello" 'hello'
不能有尾随逗号 [1, 2, 3] [1, 2, 3,]
不能有注释 {"a": 1} {"a": 1 // 注释}
数字不能有前导零 42 042

二、常见错误示例

复制代码
// ❌ 错误1:键没有引号
{name: "张三"}

// ❌ 错误2:用了单引号
{'name': '张三'}

// ❌ 错误3:尾随逗号
{"a": 1, "b": 2,}

// ❌ 错误4:注释
{
    "a": 1  // 这是注释
}

// ❌ 错误5:NaN、Infinity(JSON 不支持)
{"value": NaN}

// ✅ 正确写法
{"name": "张三", "age": 25}

第四部分:为什么项目中用 JSON

一、JSON vs 其他格式

格式 可读性 体积 解析速度 语言支持
JSON ✅ 好 所有语言
XML ✅ 好 所有语言
YAML ✅ 最好 部分语言
Protobuf ❌ 二进制 最小 最快 需编译
自定义文本 视情况 需自己实现

二、JSON 的三大优势

三、项目中的典型场景

场景 示例
前后端通信 浏览器发 {"username":"admin","password":"123"} 给服务器
配置文件 程序的 config.json 存数据库地址、端口等
API 响应 服务器返回 {"code":0,"data":[...],"msg":"成功"}
日志记录 每条日志是一个 JSON 对象
消息队列 生产者发送 JSON,消费者解析
数据库存储 MongoDB 直接存 JSON,Redis 存 JSON 字符串

第五部分:C/C++ 项目中使用 JSON

一、常用 JSON 库

语言 特点 推荐度
cJSON C 轻量、单文件、无依赖 ⭐⭐⭐⭐⭐
nlohmann/json C++ 现代 C++ 接口、简洁 ⭐⭐⭐⭐⭐
RapidJSON C++ 腾讯开源、性能极高 ⭐⭐⭐⭐
jsoncpp C++ 老牌库 ⭐⭐⭐

二、cJSON 使用示例(C 语言)

安装:cJSON 只有两个文件,直接拖进项目即可。

bash 复制代码
# 下载
git clone https://github.com/DaveGamble/cJSON.git
# 复制 cJSON.c 和 cJSON.h 到项目

生成 JSON

cpp 复制代码
#include <stdio.h>
#include "cJSON.h"

int main() {
    // 创建根对象
    cJSON* root = cJSON_CreateObject();

    // 添加字段
    cJSON_AddStringToObject(root, "name", "张三");
    cJSON_AddNumberToObject(root, "age", 25);
    cJSON_AddBoolToObject(root, "isStudent", 0);

    // 创建数组
    cJSON* hobbies = cJSON_CreateArray();
    cJSON_AddItemToArray(hobbies, cJSON_CreateString("读书"));
    cJSON_AddItemToArray(hobbies, cJSON_CreateString("编程"));
    cJSON_AddItemToObject(root, "hobbies", hobbies);

    // 创建嵌套对象
    cJSON* address = cJSON_CreateObject();
    cJSON_AddStringToObject(address, "city", "北京");
    cJSON_AddItemToObject(root, "address", address);

    // 输出为字符串
    char* jsonStr = cJSON_Print(root);
    printf("%s\n", jsonStr);

    // 释放内存
    free(jsonStr);
    cJSON_Delete(root);

    return 0;
}

输出

cpp 复制代码
{
    "name": "张三",
    "age": 25,
    "isStudent": false,
    "hobbies": ["读书", "编程"],
    "address": {
        "city": "北京"
    }
}

解析 JSON

cpp 复制代码
#include <stdio.h>
#include "cJSON.h"

int main() {
    const char* jsonStr = "{\"name\":\"张三\",\"age\":25,\"hobbies\":[\"读书\",\"编程\"]}";

    // 解析
    cJSON* root = cJSON_Parse(jsonStr);
    if (root == NULL) {
        printf("解析失败\n");
        return -1;
    }

    // 读取字符串
    cJSON* name = cJSON_GetObjectItem(root, "name");
    if (name && cJSON_IsString(name)) {
        printf("name: %s\n", name->valuestring);
    }

    // 读取数字
    cJSON* age = cJSON_GetObjectItem(root, "age");
    if (age && cJSON_IsNumber(age)) {
        printf("age: %d\n", age->valueint);
    }

    // 读取数组
    cJSON* hobbies = cJSON_GetObjectItem(root, "hobbies");
    if (hobbies && cJSON_IsArray(hobbies)) {
        int size = cJSON_GetArraySize(hobbies);
        printf("hobbies (%d):\n", size);
        for (int i = 0; i < size; i++) {
            cJSON* item = cJSON_GetArrayItem(hobbies, i);
            printf("  %s\n", item->valuestring);
        }
    }

    // 释放
    cJSON_Delete(root);
    return 0;
}

输出

name: 张三

age: 25

hobbies (2):

读书

编程

三、nlohmann/json 使用示例(C++)

安装:只需一个头文件。

bash 复制代码
# 下载 json.hpp
wget https://github.com/nlohmann/json/releases/download/v3.11.3/json.hpp
cpp 复制代码
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;

int main() {
    // ===== 构建 JSON =====
    json j;
    j["name"] = "张三";
    j["age"] = 25;
    j["hobbies"] = {"读书", "编程", "跑步"};
    j["address"]["city"] = "北京";
    j["address"]["district"] = "海淀区";

    // 输出为格式化字符串
    std::cout << j.dump(4) << std::endl;

    // ===== 解析 JSON =====
    std::string jsonStr = R"({
        "name": "李四",
        "age": 30,
        "hobbies": ["游泳", "摄影"]
    })";

    json parsed = json::parse(jsonStr);

    // 读取
    std::cout << "name: " << parsed["name"] << std::endl;
    std::cout << "age: " << parsed["age"] << std::endl;

    for (const auto& h : parsed["hobbies"]) {
        std::cout << "  hobby: " << h << std::endl;
    }

    // 判断字段是否存在
    if (parsed.contains("phone")) {
        std::cout << "有 phone 字段" << std::endl;
    } else {
        std::cout << "没有 phone 字段" << std::endl;
    }

    return 0;
}

输出

cpp 复制代码
{
    "address": {
        "city": "北京",
        "district": "海淀区"
    },
    "age": 25,
    "hobbies": ["读书", "编程", "跑步"],
    "name": "张三"
}
name: 李四
age: 30
  hobby: 游泳
  hobby: 摄影
没有 phone 字段

第六部分:项目中的 JSON 设计规范

一、API 响应的标准格式

cpp 复制代码
{
    "code": 0,
    "message": "success",
    "data": {
        "id": 1001,
        "name": "张三"
    }
}
字段 作用
code 状态码:0 表示成功,非 0 表示错误
message 错误描述(成功时可省略)
data 实际数据(可以是对象、数组、null)

二、分页响应

cpp 复制代码
{
    "code": 0,
    "data": {
        "list": [
            {"id": 1, "name": "张三"},
            {"id": 2, "name": "李四"}
        ],
        "total": 100,
        "page": 1,
        "pageSize": 10
    }
}

三、错误响应

cpp 复制代码
{
    "code": 1001,
    "message": "用户名或密码错误",
    "data": null
}

第七部分:JSON 的常见坑

转义字符速查

原字符 JSON 中的写法
" \"
\ \\
换行 \n
制表符 \t
回车 \r

总结

一、核心要点

要点 内容
定义 轻量级文本数据格式,用对象和数组表示结构
六种类型 字符串、数字、布尔、null、对象、数组
语法规则 双引号、无尾随逗号、无注释
项目用途 前后端通信、配置、日志、API 响应
C 库 cJSON(单文件、轻量)
C++ 库 nlohmann/json(现代、简洁)

二、一句话记忆

JSON 用 {} 表示对象、[] 表示数组,支持字符串、数字、布尔、null 六种类型。语法要求双引号、无注释、无尾随逗号。项目中主要用于前后端通信和配置存储,C 用 cJSON、C++ 用 nlohmann/json。

相关推荐
名字还没想好☜2 小时前
Go 用 json.Decoder 流式解析大 JSON:边读边处理不爆内存
开发语言·后端·golang·go·json
gf13211113 小时前
【python_发送飞书卡片消息_直接组装JSON格式发送卡片】
python·json·飞书
有梦想的咕噜6 小时前
Newtonsoft.Json (Json.NET) 常用方法汇总
linux·json·.net
数据狐(Datafox)1 天前
京东商品列表API接口解析(附 JSON 样例)
数据库·爬虫·json
mengzhi啊2 天前
缓存类CacheDataManager把临时数据存入json。做成插件·
qt·缓存·json
golang学习记2 天前
Go 1.27新特性: json/v2使用有趣指南
开发语言·golang·json
Token掘金室2 天前
JSON模式结构化输出报错
java·服务器·json
她说..2 天前
MySQL JSON 处理学习文档
学习·mysql·json
数据狐(Datafox)2 天前
京东商品详情API接口解析(附 JSON 样例)
java·开发语言·json