使用nlohmann/json库可高效解析JSON到std::map,其头文件设计、C++风格API及类型安全特性使其成为首选;通过std::map<std::string, json>可灵活处理嵌套结构,而数组宜用std::vector,必要时可按键值转为std::map以实现快速查找。

在C++中将JSON解析为
std::map
nlohmann/json
std::map<std::string, T>
json
使用
nlohmann/json
std::map
首先,你需要确保项目中包含了
nlohmann/json
json.hpp
#include <iostream>
#include <string>
#include <map>
#include "json.hpp" // 假设json.hpp在你的include路径中
// 为了方便,使用nlohmann::json的别名
using json = nlohmann::json;
int main() {
std::string json_string = R"({
"name": "Alice",
"age": 30,
"city": "New York",
"occupation": "Engineer"
})";
try {
// 1. 解析JSON字符串
json j = json::parse(json_string);
// 2. 将JSON对象的内容提取到std::map<std::string, std::string>
// 注意:这种直接转换只适用于JSON对象的所有值都是字符串的情况。
// 如果值类型不一致,或者有嵌套结构,你需要更细致的处理。
std::map<std::string, std::string> string_map;
for (json::iterator it = j.begin(); it != j.end(); ++it) {
// 尝试将值转换为字符串。如果值不是字符串类型,这里可能会抛出异常
// 或者进行隐式转换(如果nlohmann/json支持)。
// 更安全的做法是先检查类型:if (it.value().is_string())
string_map[it.key()] = it.value().get<std::string>();
}
std::cout << "Parsed into std::map<std::string, std::string>:" << std::endl;
for (const auto& pair : string_map) {
std::cout << " " << pair.first << ": " << pair.second << std::endl;
}
std::cout << "\n----------------------------------\n" << std::endl;
// 3. 更通用的方法:将JSON对象转换为std::map<std::string, json>
// 这种方式可以保留原始JSON的类型和结构,包括嵌套对象和数组。
std::map<std::string, json> generic_map = j.get<std::map<std::string, json>>();
std::cout << "Parsed into std::map<std::string, nlohmann::json>:" << std::endl;
for (const auto& pair : generic_map) {
std::cout << " " << pair.first << ": " << pair.second.dump() << std::endl;
}
// 4. 从std::map<std::string, json>中获取特定类型的值
if (generic_map.count("age") && generic_map["age"].is_number_integer()) {
int age = generic_map["age"].get<int>();
std::cout << "\nAge from generic_map: " << age << std::endl;
}
} catch (const json::parse_error& e) {
std::cerr << "JSON parsing error: " << e.what() << std::endl;
} catch (const json::type_error& e) {
std::cerr << "JSON type error during conversion: " << e.what() << std::endl;
} catch (const std::exception& e) {
std::cerr << "An unexpected error occurred: " << e.what() << std::endl;
}
return 0;
}这段代码展示了两种主要的转换方式:一种是直接尝试将所有值转换为特定类型(如
std::string
std::map<std::string, json>
nlohmann::json
立即学习“C++免费学习笔记(深入)”;
nlohmann/json
说实话,我个人觉得
nlohmann/json
首先,它是一个头文件库。这意味着你不需要编译额外的库文件,直接把
json.hpp
#include
其次,它的API设计非常C++-idiomatic。它充分利用了C++11及更高版本的特性,比如范围for循环、初始化列表、隐式类型转换等,让操作JSON对象感觉就像在操作
std::map
std::vector
[]
.at()
.dump()
from_json
to_json
再来,类型安全与灵活性兼顾。
nlohmann/json
json
json
.is_string()
.is_number()
.get<T>()
当然,也有像
RapidJSON
RapidJSON
nlohmann/json
nlohmann/json
std::map
当JSON结构开始变得复杂,比如有嵌套对象或数组时,直接将其解析到简单的
std::map<std::string, std::string>
核心思路是利用
nlohmann::json
std::map<std::string, nlohmann::json>
nlohmann::json
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include "json.hpp"
using json = nlohmann::json;
int main() {
std::string complex_json_string = R"({
"user_info": {
"id": 123,
"name": "Bob",
"email": "bob@example.com",
"preferences": {
"theme": "dark",
"notifications": true
}
},
"products_bought": [
{"product_id": "A1", "quantity": 2},
{"product_id": "B3", "quantity": 1}
],
"is_active": true
})";
try {
json j = json::parse(complex_json_string);
// 策略1: 将整个JSON解析为std::map<std::string, json>
// 这是处理复杂JSON最灵活的起点
std::map<std::string, json> root_map = j.get<std::map<std::string, json>>();
std::cout << "Root map keys and their JSON values:" << std::endl;
for (const auto& pair : root_map) {
std::cout << " Key: " << pair.first << ", Value: " << pair.second.dump() << std::endl;
}
// 策略2: 访问嵌套对象并将其解析为另一个std::map
if (root_map.count("user_info") && root_map["user_info"].is_object()) {
std::map<std::string, json> user_info_map = root_map["user_info"].get<std::map<std::string, json>>();
std::cout << "\nUser Info Map:" << std::endl;
if (user_info_map.count("name") && user_info_map["name"].is_string()) {
std::cout << " Name: " << user_info_map["name"].get<std::string>() << std::endl;
}
if (user_info_map.count("preferences") && user_info_map["preferences"].is_object()) {
std::map<std::string, json> prefs_map = user_info_map["preferences"].get<std::map<std::string, json>>();
std::cout << " Preferences Theme: " << prefs_map["theme"].get<std::string>() << std::endl;
}
}
// 策略3: 遍历JSON数组
if (root_map.count("products_bought") && root_map["products_bought"].is_array()) {
json products_array = root_map["products_bought"];
std::cout << "\nProducts Bought:" << std::endl;
for (const auto& product_item : products_array) {
// 每个数组元素都是一个JSON对象,可以再次解析为map
std::map<std::string, json> product_map = product_item.get<std::map<std::string, json>>();
std::cout << " Product ID: " << product_map["product_id"].get<std::string>()
<< ", Quantity: " << product_map["quantity"].get<int>() << std::endl;
}
}
} catch (const json::parse_error& e) {
std::cerr << "JSON parsing error: " << e.what() << std::endl;
} catch (const json::type_error& e) {
std::cerr << "JSON type error during conversion: " << e.what() << std::endl;
} catch (const std::exception& e) {
std::cerr << "An unexpected error occurred: " << e.what() << std::endl;
}
return 0;
}通过将外部对象解析到
std::map<std::string, json>
json
int
std::string
bool
std::map
std::vector
对于更复杂的、结构固定的JSON,你还可以定义C++结构体,并使用
nlohmann/json
from_json
to_json
std::map
std::vector
std::map
JSON数组和C++的
std::vector
std::vector
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include "json.hpp"
using json = nlohmann::json;
int main() {
std::string array_json_string = R"([
{"id": 1, "name": "Item A"},
{"id": 2, "name": "Item B", "status": "active"},
{"id": 3, "name": "Item C"}
])";
std::string mixed_array_json_string = R"([
"apple",
123,
true,
{"color": "red"}
])";
try {
// 解析数组到std::vector<json>
json j_array = json::parse(array_json_string);
std::vector<json> items_vector = j_array.get<std::vector<json>>();
std::cout << "Parsed JSON array into std::vector<nlohmann::json>:" << std::endl;
for (const auto& item_json : items_vector) {
// 每个item_json本身又是一个JSON对象,可以进一步解析到map
std::map<std::string, json> item_map = item_json.get<std::map<std::string, json>>();
std::cout << " ID: " << item_map["id"].get<int>()
<< ", Name: " << item_map["name"].get<std::string>();
if (item_map.count("status")) { // 检查可选字段
std::cout << ", Status: " << item_map["status"].get<std::string>();
}
std::cout << std::endl;
}
std::cout << "\n----------------------------------\n" << std::endl;
// 解析混合类型数组
json j_mixed_array = json::parse(mixed_array_json_string);
std::vector<json> mixed_items_vector = j_mixed_array.get<std::vector<json>>();
std::cout << "Parsed mixed JSON array into std::vector<nlohmann::json>:" << std::endl;
for (const auto& item : mixed_items_vector) {
std::cout << " Item (type: " << item.type_name() << "): " << item.dump() << std::endl;
}
} catch (const json::parse_error& e) {
std::cerr << "JSON parsing error: " << e.what() << std::endl;
} catch (const json::type_error& e) {
std::cerr << "JSON type error during conversion: " << e.what() << std::endl;
} catch (const std::exception& e) {
std::cerr << "An unexpected error occurred: " << e.what() << std::endl;
}
return 0;
}如你所见,
nlohmann/json
std::vector<T>
T
int
std::string
bool
nlohmann::json
那么,什么时候会把JSON数组解析到
std::map
map
{
"categories": [
{"id": "electronics", "items": [...]},
{"id": "books", "items": [...]}
]
}在这种情况下,
categories
id
categories
id
map
items
map
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include "json.hpp"
using json = nlohmann::json;
int main() {
std::string categories_json_string = R"({
"categories": [
{"id": "electronics", "name": "Electronics Devices", "count": 120},
{"id": "books", "name": "Books & Literature", "count": 350},
{"id": "clothing", "name": "Apparel", "count": 200}
]
})";
try {
json j_root = json::parse(categories_json_string);
// 目标:将categories数组转换为map,键是id,值是整个类别对象
std::map<std::string, json> categories_by_id;
if (j_root.count("categories") && j_root["categories"].is_array()) {
for (const auto& category_json : j_root["categories"]) {
if (category_json.is_object() && category_json.count("id") && category_json["id"].is_string()) {
std::string category_id = category_json["id"].get<std::string>();
categories_by_id[category_id] = category_json; // 将整个JSON对象作为值
}
}
}
std::cout << "Categories mapped by ID:" << std::endl;
if (categories_by_id.count("books")) {
std::cout << " Books Category Name: " << categories_by_id["books"]["name"].get<std::string>() << std::endl;
}
if (categories_by_id.count("electronics")) {
std::cout << " Electronics Item Count: " << categories_by_id["electronics"]["count"].get<int>() << std::endl;
}
} catch (const json::parse_error& e) {
std::cerr << "JSON parsing error: " << e.what() << std::endl;
} catch (const json::type_error& e) {
std::cerr << "JSON type error during conversion: " << e.what() << std::endl;
} catch (const std::exception& e) {以上就是如何在C++中将JSON解析为map_C++ JSON解析库应用实践的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号