C++之JsonCPP学习手册

简介

JSONcpp是一款开源的C++库,专门用于解析和生成JSON格式的数据。它支持STL风格的API并且容易使用,下面是JSONcpp的学习手册。

环境搭建

使用JSONcpp需要在您的项目中包含jsoncpp.h头文件,链接jsoncpp库文件。在Windows环境下,您可以通过将头文件和库文件复制到您的项目中,然后将库文件添加到您的工程中,就可以使用JSONcpp了。在UNIX/Linux环境下,您可以使用包管理工具来安装JSONcpp库。

JSONcpp的基本用法

(1) 将JSON文本字符串解析成JSONValue对象

#include 
  
	#include 
  
	 
  
	int main() {
  
	    // JSON文本字符串
  
	    std::string jsonString = "{\"name\" : \"John Smith\", \"age\" : 30}";
  
	 
  
	    // 解析JSON文本字符串
  
	    Json::Value root;
  
	    Json::Reader reader;
  
	 
  
	    if (reader.parse(jsonString, root)) {
  
	        std::cout << "name: " << root["name"].asString() << std::endl;
  
	        std::cout << "age: " << root["age"].asInt() << std::endl;
  
	    } else {
  
	        std::cout << "parse error!" << std::endl;
  
	    }
  
	 
  
	    return 0;
  
	}

(2) 从JSONValue对象中获取JSON值

#include 
  
	#include 
  
	 
  
	int main() {
  
	    // JSON文本字符串
  
	    std::string jsonString = "{\"name\" : \"John Smith\", \"age\" : 30}";
  
	 
  
	    // 解析JSON文本字符串
  
	    Json::Value root;
  
	    Json::Reader reader;
  
	 
  
	    if (reader.parse(jsonString, root)) {
  
	        std::cout << "name: " << root["name"].asString() << std::endl;
  
	        std::cout << "age: " << root["age"].asInt() << std::endl;
  
	    } else {
  
	        std::cout << "parse error!" << std::endl;
  
	    }
  
	 
  
	    // 从JSONValue对象中获取值
  
	    std::string name = root.get("name", "default_name").asString();
  
	    int age = root.get("age", 0).asInt();
  
	 
  
	    return 0;
  
	}

(3) 将JSONValue对象转换为JSON文本字符串

#include 
  
	#include 
  
	 
  
	int main() {
  
	    // 构造JSON对象
  
	    Json::Value root;
  
	    root["name"] = "John Smith";
  
	    root["age"] = 30;
  
	 
  
	    // 转换为JSON文本字符串
  
	    Json::FastWriter writer;
  
	    std::string jsonString = writer.write(root);
  
	 
  
	    std::cout << "jsonString: " << jsonString << std::endl;
  
	 
  
	    return 0;
  
	}

(4) 数组的使用

#include 
  
	#include 
  
	 
  
	int main() {
  
	    // 构造JSON数组
  
	    Json::Value arr(Json::arrayValue);
  
	    arr.append("apple");
  
	    arr.append("banana");
  
	 
  
	    // 转换为JSON文本字符串
  
	    Json::FastWriter writer;
  
	    std::string jsonString = writer.write(arr);
  
	 
  
	    std::cout << "jsonString: " << jsonString << std::endl;
  
	 
  
	    return 0;
  
	}

(5) 嵌套的JSON对象

#include 
  
	#include 
  
	 
  
	int main() {
  
	    // 构造嵌套的JSON对象
  
	    Json::Value root;
  
	    root["person"]["name"] = "John Smith";
  
	    root["person"]["age"] = 30;
  
	 
  
	    // 转换为JSON文本字符串
  
	    Json::FastWriter writer;
  
	    std::string jsonString = writer.write(root);
  
	 
  
	    std::cout << "jsonString: " << jsonString << std::endl;
  
	 
  
	    return 0;
  
	}

JSONcpp的高级用法

(1) 解析策略

默认情况下,JSONcpp在解析JSON文本字符串时对行内注释和C风格注释不做处理。如果您需要解析这些注释,可以设置解析策略。

#include 
  
	#include 
  
	 
  
	int main() {
  
	    // JSON文本字符串
  
	    std::string jsonString =
  
	        "{\n"
  
	        "    \"name\" : \"John Smith\", // name\n"
  
	        "    \"age\" : 30 /* age */\n"
  
	        "}";
  
	 
  
	    // 设置解析策略
  
	    Json::CharReaderBuilder builder;
  
	    builder["collectComments"] = true;
  
	 
  
	    // 解析JSON文本字符串
  
	    Json::Value root;
  
	    std::string errors;
  
	    std::istringstream is(jsonString);
  
	    if (Json::parseFromStream(builder, is, &root, &errors)) {
  
	        std::cout << "name: " << root["name"].asString() << std::endl;
  
	        std::cout << "age: " << root["age"].asInt() << std::endl;
  
	    } else {
  
	        std::cout << "parse error: " << errors << std::endl;
  
	    }
  
	 
  
	    return 0;
  
	}

(2) JSON对象的合并

#include 
  
	#include 
  
	 
  
	int main() {
  
	    // 构造JSON对象1
  
	    Json::Value root1;
  
	    root1["name"] = "John Smith";
  
	    root1["age"] = 30;
  
	 
  
	    // 构造JSON对象2
  
	    Json::Value root2;
  
	    root2["gender"] = "male";
  
	    root2["country"] = "USA";
  
	 
  
	    // 合并JSON对象
  
	    root1.merge(root2);
  
	 
  
	    // 转换为JSON文本字符串
  
	    Json::FastWriter writer;
  
	    std::string jsonString = writer.write(root1);
  
	 
  
	    std::cout << "jsonString: " << jsonString << std::endl;
  
	 
  
	    return 0;
  
	}
  

(3) JSON对象的比较

JSONcpp库提供了两种JSON对象比较的方式:值比较和结构比较。
值比较: 值比较是指根据JSON对象中的值进行比较。JSON对象之间的值比较,包括字符串、数字、布尔值、null等数据类型。

Json::Value obj1, obj2;
  
	obj1["name"] = "John Smith";
  
	obj1["age"] = 30;
  
	obj2["name"] = "John Smith";
  
	obj2["age"] = 30;
  
	bool isEqual = (obj1 == obj2); // true

结构比较: 结构比较是指根据JSON对象的结构进行比较。JSON对象之间的结构比较,包括对象、数组等数据类型。

Json::Value obj1, obj2;
  
	obj1["name"] = "John Smith";
  
	obj1["age"] = 30;
  
	obj2["age"] = 30;
  
	obj2["name"] = "John Smith";
  
	bool isEqual = (obj1 == obj2); // false

在进行JSON对象比较时,可以使用Value::compare()函数。
如果JSON对象相等,则返回0,如果JSON对象不相等,则返回-1或1。如果两个对象都是数组,则它们的元素将按顺序进行比较,如果两个数组长度相等且元素都相等,则返回0,否则返回-1或1。

Json::Value obj1, obj2;
  
	obj1["name"] = "John Smith";
  
	obj1["age"] = 30;
  
	obj2["age"] = 30;
  
	obj2["name"] = "John Smith";
  
	int result = obj1.compare(obj2);
  
	if (result == 0) {
  
	    std::cout << "obj1 equals obj2" << std::endl;
  
	} else if (result < 0) {
  
	    std::cout << "obj1 is smaller than obj2" << std::endl;
  
	} else {
  
	    std::cout << "obj1 is larger than obj2" << std::endl;
  
	}

需要注意的是,使用Value::compare()函数进行JSON对象比较时,如果两个对象的结构不一样,则返回的结果可能不准确。因此,在进行JSON对象比较时,最好使用值比较或结构比较。

(4) 自定义序列化与反序列化

如果您需要处理的数据无法通过JSONcpp的默认序列化和反序列化方法来进行处理,您可以通过自定义方法来对数据进行序列化和反序列化。

自定义序列化方法

bool MyWriter::write(Json::Value const& root, std::ostream* const output) {
  
	    // 将数据序列化为JSON文本字符串,并输出到流对象中
  
	    stream << "{\"name\":\"" << root["name"].asString() << "\","
  
	           << "\"age\":" << root["age"].asInt() << "}";
  
	    *output << stream.str();
  
	    return true;
  
	}
  
	 
  
	Json::StreamWriterBuilder builder;
  
	builder["indentation"] = ""; // 禁用缩进
  
	builder["commentStyle"] = "None"; //禁用注释
  
	std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
  
	MyWriter myWriter;
  
	writer->writeValue(root, (Json::Value&)myWriter);

自定义反序列化方法:

bool MyReader::parse(const char* beginDoc, const char* endDoc,
  
	    Json::Value& root, std::string& errs) {
  
	    // 从JSON文本字符串中解析数据
  
	    std::string doc(beginDoc, endDoc);
  
	    std::regex pattern("\"name\":\"(.*?)\",\"age\":([0-9]*)");
  
	    std::smatch match;
  
	    std::regex_search(doc, match, pattern);
  
	    if (match.size() == 3) {
  
	        root["name"] = match[1].str();
  
	        root["age"] = std::stoi(match[2].str());
  
	        return true;
  
	    } else {
  
	        errs = "parse error!";
  
	        return false;
  
	    }
  
	}
  
	 
  
	// 使用自定义的反序列化方法
  
	Json::CharReaderBuilder builder;
  
	MyReader myReader;
  
	std::istringstream is("{\"name\":\"John Smith\",\"age\":30}");
  
	Json::Value root;
  
	if (!Json::parseFromStream(builder, is, &root, nullptr, (Json::CharReader*)&myReader)) {
  
	    std::cout << "parse error!" << std::endl;
  
	} else {
  
	    std::cout << "name: " << root["name"].asString() << std::endl;
  
	    std::cout << "age: " << root["age"].asInt() << std::endl;
  
	}
  

(5) JSON数据校验

JSONcpp提供了一个易于使用的JSON数据校验类Json::Validator,它可以用于校验JSON对象是否符合指定的模式。

	std::string schema_string = "{\"type\":\"object\",\"properties\":{\"name\":{\"type\":\"string\"},\"age\":{\"type\":\"number\"}}}";
  
	 
  
	Json::Reader schema_reader;
  
	Json::Value schema;
  
	if (!schema_reader.parse(schema_string, schema)) {
  
	    std::cout << "parse schema error!" << std::endl;
  
	    return -1;
  
	}
  
	 
  
	Json::FastWriter writer;
  
	Json::Value root;
  
	root["name"] = "John Smith";
  
	root["age"] = "Invalid Age"; // 数据不合法,将导致校验失败
  
	 
  
	Json::Value errors;
  
	Json::CharReaderBuilder builder;
  
	builder["collectComments"] = true;
  
	Json::Value settings;
  
	settings["allowComments"] = true;
  
	settings["allowTrailingCommas"] = true;
  
	 
  
	std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
  
	if (!Json::validate(schema, settings, *reader, (const char*) writer.write(root).c_str(), errors)) {
  
	    std::cout << "validate error: " << errors.toStyledString() << std::endl;
  
	} else {
  
	    std::cout << "validate success!" << std::endl;
  
	}

(6) 跨平台支持

JSONcpp是一种跨平台的C++库,支持Windows、Linux、Mac OS等多种操作系统。在Windows环境下,您可以使用Microsoft Visual Studio来编译和运行JSONcpp库。在Linux环境下,您可以使用GNU编译器来编译和运行JSONcpp库。如果您在跨平台项目中使用JSONcpp库,您可以为不同的操作系统编写特定的Makefile来实现自动化编译和部署。 以上就是JSONcpp的学习手册,希望能够帮助您更好地学习和使用Jsoncpp库。

注意

注意,本文生成自ChatGPT

你可能感兴趣的:(c++,json)