Linux(程序设计):31---jsoncpp库(C++操作JSON)
Posted 董哥的黑板报
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux(程序设计):31---jsoncpp库(C++操作JSON)相关的知识,希望对你有一定的参考价值。
一、jsoncpp库概述- jsoncpp是一个c++封装的json包,跨平台支持windows、linux、unix等多系统
- jsoncpp源码地址:https://github.com/open-source-parsers/jsoncpp
库的安装
sudo apt-get install libjsoncpp-dev
- 安装完成之后,头文件默认安装在/usr/include/jsoncpp/json/目录下,库API文档默认在/usr/share/doc/libjsoncpp-dev/目录下
二、jsoncpp支持的值编译带有jsoncpp库的C++程序
- 使用如下的命令进行编译,编译时带上-ljsoncpp选项即可
- 例如:
g++ jsoncpp_demo01.c -o demo01 -ljsoncpp -std=c++11
- jsoncpp 使用 Json::Value 对象来保存 JSON 串,Json::Value 对象可以表示如下数据类 型:
检测保存的数据类型
bool isNull() const; bool isBool() const; bool isInt() const; bool isInt64() const; bool isUInt() const; bool isUInt64() const; bool isIntegral() const; bool isDouble() const; bool isNumeric() const; bool isString() const; bool isArray() const; bool isObject() const;
基础数据类型的访问
const char* asCString() const; JSONCPP_STRING asString() const; Int asInt() const; UInt asUInt() const; Int64 asInt64() const; UInt64 asUInt64() const; LargestInt asLargestInt() const; LargestUInt asLargestUInt() const; float asFloat() const; double asDouble() const; bool asBool() const;
数组风格
- ValueType::arrayValue 和 ValueType::objectValue 数据类型的访问,操作方式很类似 C++的 vector,可以使用数组风格或者迭代器风格来操作数据。例如:
root["name"] = "milo";
- 下面是相关接口
ArrayIndex size() const; Value& operator[](ArrayIndex index); Value& operator[](int index); const Value& operator[](ArrayIndex index) const; const Value& operator[](int index) const; Value get(ArrayIndex index, const Value& defaultValue) const; const_iterator begin() const; const_iterator end() const; iterator begin(); iterator end();
- ValueType::objectValue 数据类型的访问,操作方式很类似 C++的 map
Value& operator[](const char* key); const Value& operator[](const char* key) const; Value& operator[](const JSONCPP_STRING& key); const Value& operator[](const JSONCPP_STRING& key) const; Value& operator[](const StaticString& key); Value& operator[](const CppTL::ConstString& key); const Value& operator[](const CppTL::ConstString& key) const; Value get(const char* key, const Value& defaultValue) const; Value get(const char* begin, const char* end, const Value& defaultValue) const; Value get(const JSONCPP_STRING& key, const Value& defaultValue) const; Value get(const CppTL::ConstString& key, const Value& defaultValue) const;
四、注意事项修改数据
- 知道如何获取 Json::Value 对象或其子对象后,我们来看下如何修改 Json::Value 保存 的数据:
- 直接使用=赋值就可以了
Value& operator=(Value other);
- 因为 Json::Value 已经实现了各种数据类型的构造函数
Value(ValueType type = nullValue); Value(Int value); Value(UInt value); Value(Int64 value); Value(UInt64 value); Value(double value); Value(const char* value); Value(const char* begin, const char* end); Value(const StaticString& value); Value(const JSONCPP_STRING& value); Value(const CppTL::ConstString& value); Value(bool value); Value(const Value& other); Value(Value&& other);
类型转换
- 对于Int、Uint、Int64、UInt64等类型,注意类型。
root["age"] = 80; //默认为Int类型
- 可以使用下面的方式进行强制类型转换
root["age"] = (Json::Uint)80;
五、演示案例1空值
- 如果要将变量设置为 null,应该使用如下的方式
root["address"] = Json::nullValue;
六、演示案例2代码如下
#include <iostream> #include <string> #include <jsoncpp/json/json.h> int main() { std::cout << "Hello World!" << std::endl; Json::Value root; Json::FastWriter fast; root["ModuleType"] = Json::Value(1); root["ModuleCode"] = Json::Value("China"); std::cout<<fast.write(root)<<std::endl; Json::Value sub; sub["version"] = Json::Value("1.0"); sub["city"] = Json::Value(root); fast.write(sub); std::cout<<sub.toStyledString()<<std::endl; return 0; }
- 编译运行如下:
g++ jsoncpp_demo01.c -o demo01 -ljsoncpp -std=c++11
七、演示案例3代码如下
#include <string> #include <jsoncpp/json/json.h> #include <iostream> using namespace std; void readJson() { std::string strValue = "{\\"name\\":\\"json\\",\\"array\\":[{\\"cpp\\":\\"jsoncpp\\"},{\\"java\\":\\"jsoninjava\\"},{\\"php\\":\\"support\\"}]}"; Json::Reader reader; Json::Value value; if (reader.parse(strValue, value)) { std::string out = value["name"].asString(); std::cout << out << std::endl; const Json::Value arrayObj = value["array"]; for (unsigned int i = 0; i < arrayObj.size(); i++) { if (!arrayObj[i].isMember("cpp")) continue; out = arrayObj[i]["cpp"].asString(); std::cout << out; if (i != (arrayObj.size() - 1)) std::cout << std::endl; } } } void writeJson() { Json::Value root; Json::Value arrayObj; Json::Value item; item["cpp"] = "jsoncpp"; item["java"] = "jsoninjava"; item["php"] = "support"; arrayObj.append(item); root["name"] = "json"; root["array"] = arrayObj; root.toStyledString(); std::string out = root.toStyledString(); std::cout << out << std::endl; } int main(int argc, char** argv) { readJson(); writeJson(); return 0; }
- 编译运行如下:
g++ jsoncpp_demo02.c -o demo02 -ljsoncpp -std=c++11
代码如下
//测试jsoncpp的使用方法和性能 #include <memory> #include <sstream> #include <iostream> #include <stdint.h> #include <unistd.h> #include <sys/time.h> #include <sys/wait.h> #include "jsoncpp/json/json.h" #include "jsoncpp/json/value.h" #include "jsoncpp/json/reader.h" #include "jsoncpp/json/writer.h" /* { "name": "milo", "age": 80, "languages": ["C++", "C"], "phone": { "number": "186****3143", "type": "home" }, "books":[ { "name": "Linux kernel development", "price":7.7 }, { "name": "Linux server development", "price": 8.0 } ], "vip":true, "address": null } */ static uint64_t getNowTime() { struct timeval tval; uint64_t nowTime; gettimeofday(&tval, NULL); nowTime = tval.tv_sec * 1000L + tval.tv_usec / 1000L; return nowTime; } std::string JsoncppEncodeNew() { std::string jsonStr; // 一个value是可以包含多个键值对 Json::Value root, languages, phone, book, books; // 姓名 root["name"] = "milo"; // 年龄 root["age"] = 80; // 语言 languages[0] = "C++"; languages[1] = "Java"; root["languages"] = languages; // 电话 phone["number"] = "186****3143"; phone["type"] = "home"; root["phone"] = phone; // 书籍 book["name"] = "Linux kernel development"; book["price"] = 7.7; books[0] = book; // 深拷贝 book["name"] = "Linux server development"; book["price"] = 8.0; books[1] = book; // 深拷贝 root["books"] = books; // 是否为vip root["vip"] = true; // address信息空null root["address"] = "yageguoji"; Json::StreamWriterBuilder writerBuilder; std::ostringstream os; std::unique_ptr<Json::StreamWriter> jsonWriter(writerBuilder.newStreamWriter()); jsonWriter->write(root, &os); jsonStr = os.str(); // std::cout << "Json:\\n" << jsonStr << std::endl; return jsonStr; } std::string JsoncppEncodeOld() { std::string jsonStr; Json::Value root, languages, phone, book, books; // 姓名 root["name"] = "milo"; //root["name"] = Json::nullValue; // 年龄 root["age"] = 80; // 语言 languages[0] = "C++"; languages[1] = "Java"; root["languages"] = languages; // 电话 phone["number"] = "186****3143"; phone["type"] = "home"; root["phone"] = phone; // 书籍 book["name"] = "Linux kernel development"; book["price"] = (float)7.7; books[0] = book; book["name"] = "Linux server development"; book["price"] = (float)8.0; books[1] = book; root["books"] = books; // 是否为vip root["vip"] = true; // address信息空null root["address"] = "yageguoji"; //;// Json::nullValue; // 如果是null,则要用自定义的Json::nullValue,不能用NULL Json::FastWriter writer; jsonStr = writer.write(root); // std::cout << "Json:\\n" << jsonStr << std::endl; return jsonStr; } // 不能返回引用 Json::Value JsoncppEncodeOldGet() { Json::Value root; Json::Value languages, phone, book, books; // 姓名 root["name"] = "milo"; //root["name"] = Json::nullValue; // 年龄 root["age"] = 80; // 语言 languages[0] = "C++"; languages[1] = "Java"; root["languages"] = languages; // 电话 phone["number"] = "186****3143"; phone["type"] = "home"; root["phone"] = phone; // 书籍 book["name"] = "Linux kernel development"; book["price"] = (float)7.7; books[0] = book; book["name"] = "Linux server development"; book["price"] = (float)8.0; books[1] = book; root["books"] = books; // 是否为vip root["vip"] = true; // address信息空null root["address"] = Json::nullValue; //"yageguoji";// Json::nullValue; // 如果是null,则要用自定义的Json::nullValue,不能用NULL std::cout << "JsoncppEncodeOldGet:\\n" << std::endl; return root; } void printJsoncpp(Json::Value &root) { if(root["name"].isNull()) { std::cout << "name null\\n"; } std::cout << "name: " << root["name"].asString() << std::endl; std::cout << "age: " << root["age"].asInt() << std::endl; Json::Value &languages = root["languages"]; std::cout << "languages: "; for (uint32_t i = 0; i < languages.size(); ++i) { if (i != 0) { std::cout << ", "; } std::cout << languages[i].asString(); } std::cout << std::endl; Json::Value &phone = root["phone"]; std::cout << "phone number: " << phone["number"].asString() << ", type: " << phone["type"].asString() << std::endl; Json::Value &books = root["books"]; for (uint32_t i = 0; i < books.size(); ++i) { Json::Value &book = books[i]; std::cout << "book name: " << book["name"].asString() << ", price: " << book["price"].asFloat() << std::endl; } std::cout << "vip: " << root["vip"].asBool() << std::endl; if (!root["address"].isNull()) { std::cout << "address: " << root["address"].asString() << std::endl; } else { std::cout << "address is null" << std::endl; } } bool JsoncppDecodeNew(const std::string &info) { if (info.empty()) return false; bool res; JSONCPP_STRING errs; Json::Value root; Json::CharReaderBuilder readerBuilder; std::unique_ptr<Json::CharReader> const jsonReader(readerBuilder.newCharReader()); res = jsonReader->parse(info.c_str(), info.c_str() + info.length(), &root, &errs); if (!res || !errs.empty()) { std::cout << "parseJson err. " << errs << std::endl; return false; } // printJsoncpp(root); return true; } bool JsoncppDecodeOld(const std::string &strJson) { if (strJson.empty()) return false; bool res; Json::Value root; Json::Reader jsonReader; res = jsonReader.parse(strJson, root); if (!res) { std::cout << "jsonReader.parse err. " << std::endl; return false; } // printJsoncpp(root); return true; } const char *strCjson = "{ \\ \\"name\\": \\"milo\\", \\ \\"age\\": 80, \\ \\"languages\\": [\\"C++\\", \\"C\\"],\\ \\"phone\\": { \\ \\"number\\": \\"186****3143\\", \\ \\"type\\": \\"home\\" \\ }, \\ \\"books\\": [{ \\ \\"name\\": \\"Linux kernel development\\", \\ \\"price\\": 7.700000 \\ }, { \\ \\"name\\": \\"Linux server development\\", \\ \\"price\\": 8 \\ }], \\ \\"vip\\": true, \\ \\"address\\": null \\ } \\ "; #define TEST_COUNT 100000 int main() { std::string jsonStrNew; std::string jsonStrOld; jsonStrNew = JsoncppEncodeNew(); // JsoncppEncodeNew size: 337 std::cout << "JsoncppEncodeNew size: " << jsonStrNew.size() << std::endl; std::cout << "JsoncppEncodeNew string: " << jsonStrNew << std::endl; JsoncppDecodeNew(jsonStrNew); jsonStrOld = JsoncppEncodeOld(); // JsoncppEncodeOld size: 248 std::cout << "\\n\\nJsoncppEncodeOld size: " << jsonStrOld.size() << std::endl; std::cout << "JsoncppEncodeOld string: " << jsonStrOld << std::endl; JsoncppDecodeOld(jsonStrOld); Json::Value root = JsoncppEncodeOldGet(); Json::FastWriter writer; std::cout << "writer:\\n" << std::endl; std::string jsonStr = writer.write(root); std::cout << "\\n\\njsonStr string: " << jsonStrOld << std::endl; #if 1 uint64_t startTime; uint64_t nowTime; startTime = getNowTime(); std::cout << "jsoncpp encode time testing" << std::endl; for(int i = 0; i < TEST_COUNT; i++) { JsoncppEncodeNew(); } nowTime = getNowTime(); std::cout << "jsoncpp encode " << TEST_COUNT << " time, need time: " << nowTime-startTime << "ms" << std::endl; startTime = getNowTime(); std::cout << "\\njsoncpp encode time testing" << std::endl; for(int i = 0; i < TEST_COUNT; i++) { JsoncppEncodeOld(); } nowTime = getNowTime(); std::cout << "jsoncpp encode " << TEST_COUNT << " time, need time: " << nowTime-startTime << "ms" << std::endl; startTime = getNowTime(); std::cout << "\\njsoncpp decode time testing" << std::endl; for(int i = 0; i < TEST_COUNT; i++) { JsoncppDecodeNew(jsonStrNew); } nowTime = getNowTime(); std::cout << "jsoncpp decode " << TEST_COUNT << " time, need time: " << nowTime-startTime << "ms" << std::endl; startTime = getNowTime(); std::cout << "\\njsoncpp decode time testing" << std::endl; for(int i = 0; i < TEST_COUNT; i++) { JsoncppDecodeOld(jsonStrNew); } nowTime = getNowTime(); std::cout << "jsoncpp decode " << TEST_COUNT << " time, need time: " << nowTime-startTime << "ms" << std::endl; #endif return 0; }
- 编译运行如下:
g++ jsoncpp_speed.cpp -o jsoncpp_speed -ljsoncpp -std=c++11
以上是关于Linux(程序设计):31---jsoncpp库(C++操作JSON)的主要内容,如果未能解决你的问题,请参考以下文章