简介
- jsoncpp 提供了一组简单易用的 API,使得在 C++ 程序中处理 JSON 数据变得更加方便和高效。
安装
- linux环境下安装jsoncpp
sudo apt-get update
sudo apt-get install --reinstall libjsoncpp-dev
- 建立软链接确保编译器找到头文件 #include <json/json.h>
sudo ln -s /usr/include/jsoncpp/json /usr/include/json
简易demo: 基础数据读写
json数据的序列化及反序列化
/* example.cpp */
#include <iostream>
#include <fstream>
#include <json/json.h> // JSONcpp 头文件bool writeJsonToFile(const std::string &filename)
{// 创建一个 JSON 对象Json::Value root;root["key"] = "item";root["value1"] = 10;root["value2"] = 1.2345f;root["value3"] = 2.3456f;// 将 JSON 对象转换为字符串Json::StreamWriterBuilder builder;std::string jsonString = Json::writeString(builder, root);// 将 JSON 字符串写入文件std::ofstream ofs(filename);if (!ofs.is_open()){std::cerr << "Failed to open file for writing: " << filename << std::endl;return false;}ofs << jsonString;ofs.close();std::cout << "JSON data written to file: " << filename << std::endl;return true;
}bool readAndParseJsonFile(const std::string &filename)
{// 打开文件并读取 JSON 数据std::ifstream ifs(filename);if (!ifs.is_open()){std::cerr << "Failed to open file for reading: " << filename << std::endl;return false;}Json::Value root;Json::CharReaderBuilder readerBuilder;std::string errs;// 解析 JSON 数据if (!Json::parseFromStream(readerBuilder, ifs, &root, &errs)){std::cerr << "Failed to parse JSON in file: " << filename << std::endl;std::cerr << errs << std::endl;return false;}// 获取 JSON 中的字段值std::string key = root["key"].asString();int value1 = root["value1"].asInt();float value2 = root["value2"].asFloat();double value3 = root["value3"].asDouble();// 打印解析后的值std::cout << "key: " << key << std::endl;std::cout << "value1: " << value1 << std::endl;std::cout << "value2: " << value2 << std::endl;std::cout << "value3: " << value3 << std::endl;return true;
}int main()
{const std::string filename = "example.json";// 写入 JSON 数据到文件if (!writeJsonToFile(filename)){return 1;}// 从文件读取并解析 JSON 数据if (!readAndParseJsonFile(filename)){return 1;}return 0;
}
- 编译时需链接jsoncpp库
g++ example.cpp -o example -ljsoncpp
- result
升级demo: 有层级的数据结构, 包括结构体、数组
#include <iostream>
#include <fstream>
#include <vector>
#include <json/json.h> // JSONcpp 头文件struct SecurityConfig
{std::string username;std::string password;
};struct ServerConfig
{std::string address;int port;int timeout;SecurityConfig securityConfig;
};struct FeatureFlags
{bool enableFeature;
};bool writeConfigToFile(const std::string &filename, const ServerConfig &serverConfig, const std::vector<FeatureFlags> &featureFlagsList)
{// 创建一个 JSON 对象Json::Value root;// 构建服务器配置节点Json::Value serverNode;serverNode["address"] = serverConfig.address;serverNode["port"] = serverConfig.port;serverNode["timeout"] = serverConfig.timeout;// 构建安全配置节点Json::Value securityNode;securityNode["username"] = serverConfig.securityConfig.username;securityNode["password"] = serverConfig.securityConfig.password;serverNode["securityConfig"] = securityNode;root["server"] = serverNode;// 构建功能开关配置节点数组Json::Value featuresArray(Json::arrayValue);for (const auto &flags : featureFlagsList){Json::Value featureNode;featureNode["enableFeature"] = flags.enableFeature;featuresArray.append(featureNode);}root["featureFlags"] = featuresArray;// 将 JSON 对象转换为字符串Json::StreamWriterBuilder builder;std::string jsonString = Json::writeString(builder, root);// 将 JSON 字符串写入文件std::ofstream ofs(filename);if (!ofs.is_open()){std::cerr << "Failed to open file for writing: " << filename << std::endl;return false;}ofs << jsonString;ofs.close();std::cout << "JSON data written to file: " << filename << std::endl;return true;
}bool readConfigFromFile(const std::string &filename, ServerConfig &serverConfig, std::vector<FeatureFlags> &featureFlagsList)
{// 打开文件并读取 JSON 数据std::ifstream ifs(filename);if (!ifs.is_open()){std::cerr << "Failed to open file: " << filename << std::endl;return false;}// 解析 JSON 数据Json::Value root;Json::CharReaderBuilder readerBuilder;std::string errs;if (!Json::parseFromStream(readerBuilder, ifs, &root, &errs)){std::cerr << "Failed to parse JSON in file: " << filename << std::endl;std::cerr << errs << std::endl;return false;}// 解析服务器配置if (root.isMember("server")){Json::Value serverNode = root["server"];serverConfig.address = serverNode["address"].asString();serverConfig.port = serverNode["port"].asInt();serverConfig.timeout = serverNode["timeout"].asInt();// 解析安全配置if (serverNode.isMember("securityConfig")){Json::Value securityNode = serverNode["securityConfig"];serverConfig.securityConfig.username = securityNode["username"].asString();serverConfig.securityConfig.password = securityNode["password"].asString();}else{std::cerr << "Missing 'securityConfig' in JSON file." << std::endl;return false;}}else{std::cerr << "Missing 'server' configuration in JSON file." << std::endl;return false;}// 解析功能开关配置数组if (root.isMember("featureFlags")){Json::Value featuresArray = root["featureFlags"];if (featuresArray.isArray()){for (const auto &featureNode : featuresArray){FeatureFlags flags;flags.enableFeature = featureNode["enableFeature"].asBool();featureFlagsList.push_back(flags);}}else{std::cerr << "'featureFlags' is not an array in JSON file." << std::endl;return false;}}else{std::cerr << "Missing 'featureFlags' configuration in JSON file." << std::endl;return false;}return true;
}int main()
{const std::string filename = "config.json";ServerConfig serverConfig = {"127.0.0.1", 8080, 5000, {"admin", "password"}};std::vector<FeatureFlags> featureFlagsList = {{true},{false},{true}};// 将配置写入 JSON 文件if (!writeConfigToFile(filename, serverConfig, featureFlagsList)){return 1;}std::cout << "Configuration written to file: " << filename << std::endl;// 从文件读取并解析 JSON 配置数据ServerConfig readServerConfig;std::vector<FeatureFlags> readFeatureFlagsList;if (!readConfigFromFile(filename, readServerConfig, readFeatureFlagsList)){return 1;}// 打印读取的配置信息std::cout << "Server Configuration:" << std::endl;std::cout << " Address: " << readServerConfig.address << std::endl;std::cout << " Port: " << readServerConfig.port << std::endl;std::cout << " Timeout: " << readServerConfig.timeout << " ms" << std::endl;std::cout << " Security Config:" << std::endl;std::cout << " Username: " << readServerConfig.securityConfig.username << std::endl;std::cout << " Password: " << readServerConfig.securityConfig.password << std::endl;std::cout << "Feature Flags:" << std::endl;for (size_t i = 0; i < readFeatureFlagsList.size(); ++i){std::cout << " Feature " << i + 1 << " Enabled: " << (readFeatureFlagsList[i].enableFeature ? "true" : "false") << std::endl;}return 0;
}
- result
节点不存在的情况
- 节点不存在的情况会解析出默认的数据 如0或空字符串
- 主动判断节点是否存在:
// 访问不存在的节点if (root.isMember("database")){// 这里的条件不会满足,因为 JSON 文件中没有 "database" 节点Json::Value dbNode = root["database"];// 如果不存在的节点,会得到默认值std::string dbName = dbNode["name"].asString(); // 返回空字符串 ""int dbPort = dbNode["port"].asInt(); // 返回默认的整数值 0std::cout << "Database Name: " << dbName << std::endl;std::cout << "Database Port: " << dbPort << std::endl;}else{std::cerr << "Missing 'database' configuration in JSON file." << std::endl;}
附件
- josncpp源码
https://github.com/open-source-parsers/jsoncpp - 文档
https://open-source-parsers.github.io/jsoncpp-docs/doxygen/files.html