什么是json
json是一种文本规范 ,可以简单的表示树形结构 的数据,本质是一条字符串。
库的引入
cpp
#include <nlohmann/json.hpp>
using json = nlohmann::json; // 简化命名(否则每次都要写nlohmann::json)
json 对象的创建与初始化
方式 1:空对象初始化(逐步赋值)
适合不确定初始数据,后续动态添加的场景:
cpp
#include <nlohmann/json.hpp>
#include <iostream>
using json = nlohmann::json;
int main() {
json user; // 创建空JSON对象
user["name"] = "张三"; // 新增字符串键值对
user["age"] = 25; // 新增整数键值对
user["is_student"] = false; // 新增布尔值
user["hobbies"] = {"篮球", "编程"}; // 新增数组
std::cout << "空对象逐步赋值结果:" << user << std::endl;return 0;}
方式 2:初始化列表(直接赋值)
最常用场景,一次性定义完整 JSON 结构,直观简洁:
cpp
#include <nlohmann/json.hpp>
#include <iostream>
using json = nlohmann::json;
int main() {// 直接用键值对列表初始化,支持嵌套
json student = {
{"name", "李四"},
{"age", 20},
{"scores", {{"math", 90}, {"english", 85}}}, // 嵌套对象
{"hobbies", {"游泳", "阅读"}
} // 嵌套数组};
std::cout << "初始化列表创建结果:" << student << std::endl;return 0;}
方式 3:从 C++ 原生容器转换
支持vector(转 JSON 数组)和map(转 JSON 对象)直接转换:
cpp
#include <nlohmann/json.hpp>
#include <iostream>
#include <vector>
#include <map>
using json = nlohmann::json;
int main() {
// vector → JSON数组
std::vector<int> nums = {10, 20, 30, 40};
json json_nums = nums;
std::cout << "vector转JSON数组:" << json_nums << "\n\n";
// map → JSON对象
std::map<std::string, std::string> info = {{"city", "深圳"}, {"job", "程序员"}};
json json_info = info;
std::cout << "map转JSON对象:" << json_info << std::endl;return 0;}
方式 4:从 JSON 字符串解析
适合处理网络请求返回、配置文件内容等字符串格式 JSON:
cpp
#include <nlohmann/json.hpp>
#include <iostream>
using json = nlohmann::json;
int main() {// 原生字符串R"()":避免双引号转义(无需写\")
std::string json_str = R"(
{
"id": 1001,
"name": "王五",
"score": 98.5,
"tags": ["优秀", "勤奋"]
}
)";
// 解析字符串为JSON对象
json from_str = json::parse(json_str);
std::cout << "字符串解析结果:" << from_str << std::endl;return 0;}
json 数据的访问
方式1:at()方法
at(键)得到值
cpp
#include <nlohmann/json.hpp>
#include <iostream>
#include <stdexcept> // 用于异常处理
using json = nlohmann::json;
int main() {
json student = {
{"name", "李四"},
{"scores", {{"math", 90}}},
{"hobbies", {"游泳", "阅读"}}
};
try {
// 访问嵌套对象
double math_score = student.at("scores").at("math");
// 访问数组(索引从0开始)
std::string hobby1 = student.at("hobbies").at(0);
std::cout << "数学成绩:" << math_score << "\n";
std::cout << "第一个爱好:" << hobby1 << "\n";
// 访问不存在的键(触发异常)
std::string gender = student.at("gender");
} catch (const std::exception& e) {
std::cout << "访问失败:" << e.what() << std::endl;
}
return 0;
}
方式 2:[]操作符
cpp
#include <nlohmann/json.hpp>
#include <iostream>
using json = nlohmann::json;
int main() {
json student = {{"name", "李四"}, {"age", 20}};
// 确定键存在时,直接访问
std::string name = student["name"];
int age = student["age"];
std::cout << "姓名:" << name << ",年龄:" << age << "\n";
// 访问不存在的键:自动创建空值(注意:这会修改原JSON)
student["gender"]; // 新增key="gender",值为null
std::cout << "误操作后的JSON:" << student << std::endl;
return 0;
}
方式 3:value()方法
cpp
#include <nlohmann/json.hpp>
#include <iostream>
using json = nlohmann::json;
int main() {
json student = {{"name", "李四"}, {"age", 20}};
// 键存在:返回对应值
std::string name = student.value("name", "未知姓名");
// 键不存在:返回默认值25
int age = student.value("age", 25);
// 键不存在:返回默认值"男"
std::string gender = student.value("gender", "男");
std::cout << "姓名:" << name << ",年龄:" << age << ",性别:" << gender << std::endl;
return 0;
}
json数据的修改
修改已有键值
直接用=赋值覆盖旧值
直接用[]赋值(即使键不存在)
cpp
#include <nlohmann/json.hpp>
#include <iostream>
using json = nlohmann::json;
int main() {
json student = {{"name", "李四"}, {"age", 20}, {"scores", {{"english", 85}}}};
// 修改普通键值
student["age"] = 21;
// 修改嵌套键值
student["scores"]["english"] = 88;
student["scores"]["math"] = 80;
std::cout << "修改后:" << student << std::endl;
return 0;
}
数组操作(添加 / 删除元素)
JSON 数组支持push_back()(添加)、erase()(删除)等操作:
cpp
#include <nlohmann/json.hpp>
#include <iostream>
using json = nlohmann::json;
int main() {
json hobbies = {"游泳", "阅读"};
// 数组末尾添加元素
hobbies.push_back("跑步");
std::cout << "添加后:" << hobbies << "\n";
// 删除索引为1的元素(第二个元素)
hobbies.erase(1);
std::cout << "删除后:" << hobbies << "\n";
// 获取数组长度
std::cout << "数组长度:" << hobbies.size() << std::endl;
return 0;
}
json 数据的序列化与反序列化
序列化:JSON 对象 → 字符串 / 文件(用于存储、网络传输);
用dump()
cpp
#include <nlohmann/json.hpp>
#include <iostream>
using json = nlohmann::json;
int main() {
json data = {
{"name", "张三"},
{"age", 25},
{"hobbies", {"篮球", "编程"}}
};
// 紧凑格式(无缩进,适合传输/存储)
std::string compact_str = data.dump();
std::cout << "紧凑格式:" << compact_str << "\n\n";
// 带缩进格式(4个空格,易读,适合日志/配置文件)
std::string pretty_str = data.dump(4);
std::cout << "带缩进格式:\n" << pretty_str << std::endl;
return 0;
}
反序列化:字符串 / 文件 → JSON 对象(用于解析数据)。
用parse()
cpp
#include <nlohmann/json.hpp>
#include <iostream>
using json = nlohmann::json;
int main() {
// 模拟网络请求返回的JSON字符串
std::string response_str = R"({"code": 200, "msg": "success", "data": {"user_id": 1001}})";
// 解析字符串
json response = json::parse(response_str);
// 访问解析后的数据
int code = response["code"];
std::string msg = response["msg"];
int user_id = response["data"]["user_id"];
std::cout << "状态码:" << code << "\n";
std::cout << "信息:" << msg << "\n";
std::cout << "用户ID:" << user_id << std::endl;
return 0;
}
多层参数访问
cpp
std::string city = data["user"]["info"]["address"]["city"];
std::string city = data.at("user").at("info").at("address").at("city");