Linux(程序设计):31---jsoncpp库(C++操作JSON)

金鞍玉勒寻芳客,未信我庐别有春。这篇文章主要讲述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

Linux(程序设计):31---jsoncpp库(C++操作JSON)

文章图片

  • 安装完成之后,头文件默认安装在/usr/include/jsoncpp/json/目录下,库API文档默认在/usr/share/doc/libjsoncpp-dev/目录下
Linux(程序设计):31---jsoncpp库(C++操作JSON)

文章图片

编译带有jsoncpp库的C++程序
  • 使用如下的命令进行编译,编译时带上-ljsoncpp选项即可
  • 例如:
g++ jsoncpp_demo01.c -o demo01 -ljsoncpp -std=c++11

二、jsoncpp支持的值
  • jsoncpp 使用 Json::Value 对象来保存 JSON 串,Json::Value 对象可以表示如下数据类 型:
Linux(程序设计):31---jsoncpp库(C++操作JSON)

文章图片

三、相关接口
检测保存的数据类型
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;

空值
  • 如果要将变量设置为 null,应该使用如下的方式
root["address"] = Json::nullValue;

五、演示案例1
代码如下
  • Github源码链接:https://github.com/dongyusheng/csdn-code/tree/master/jsoncpp
#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

Linux(程序设计):31---jsoncpp库(C++操作JSON)

文章图片

六、演示案例2
代码如下
  • Github源码链接:https://github.com/dongyusheng/csdn-code/tree/master/jsoncpp
#include < string> #include < jsoncpp/json/json.h> #include < iostream> using namespace std; void readJson() { std::string strValue = "https://www.songbingjia.com/android/{//"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

Linux(程序设计):31---jsoncpp库(C++操作JSON)

文章图片

七、演示案例3
代码如下
  • Github源码链接:https://github.com/dongyusheng/csdn-code/tree/master/jsoncpp
//测试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,不能用NULLJson::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; #endifreturn 0; }

  • 编译运行如下:
g++ jsoncpp_speed.cpp -o jsoncpp_speed -ljsoncpp -std=c++11

Linux(程序设计):31---jsoncpp库(C++操作JSON)

文章图片

【Linux(程序设计):31---jsoncpp库(C++操作JSON)】

    推荐阅读