日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++轻量级Json解析工具—TinyJson

發(fā)布時(shí)間:2023/12/10 c/c++ 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++轻量级Json解析工具—TinyJson 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

C++輕量級Json解析工具—TinyJson

簡介

之前Json解析工具習(xí)慣于用**nlohmann/json**,后來發(fā)現(xiàn)要兼容Centos5系的系統(tǒng),且需要批量使用,系統(tǒng)升級gcc/g++升級有點(diǎn)不現(xiàn)實(shí),后來改用輕量級TinyJson庫,說一下在使用碰到的一些問題以及為了兼容性作出的修改。

TinyJson輕量級json解析工具,只需要包含頭就可以直接使用。兼容Windows/Linux平臺。Mac并沒有進(jìn)行相關(guān)測試。理論上兼容。

TinyJson相關(guān)信息

Git地址:https://github.com/button-chen/tinyjson

相關(guān)介紹,在github并沒有過的介紹,但是在百度的時(shí)候發(fā)現(xiàn)了很多關(guān)于TinyJson的介紹,有點(diǎn)亂,不一一細(xì)究了。

  • 使用樣例

在github中有相關(guān)的一些介紹,不做詳細(xì)介紹。

測試缺陷

1.兼容C++03 編譯

Lamba表達(dá)式的去除

char LastValidChar(std::string json,int index) {for (int i = index - 1; i >= 0; --i) {if (isspace(json[i])) continue;char tmp = json[i];return tmp;}return '\0'; } //-------------------------------------------------------------// //將下方的lamba表達(dá)式注釋掉,并改為添加上的函數(shù)// // 解析為 key-value 調(diào)用一次解析一個(gè)層次 inline bool ParseJson::ParseObj(std::string json) {//------注釋區(qū)域--------------//auto LastValidChar = [&](int index)->char{for (int i = index-1; i >= 0; --i){if (isspace(json[i])) continue;char tmp = json[i];return tmp;}return '\0';};//---------------------------// else if (isdigit(nextc) && LastValidChar(json,i) == ':') //-----------------修改----------------------------// //---LastValidChar(i) --LastValidChar(json,i)-----// else if (isdigit(nextc) && LastValidChar(i) == ':') {tokens = FetchNumStr(json, i, offset); }

2.不支持?jǐn)?shù)組的讀取

測試demo

std::string data = "{\"type\": \"cdk\",\"cdk\":\"18000002\",\ \"frist_reward_goods\":[\ [\"1\",\"3037\",\"100\"],\ [\"2\",\"3037\",\"100\"],\ [\"3\",\"3037\",\"100\"],\ [\"4\",\"3037\",\"100\"]]}";

TinyJson在讀取的時(shí)候,數(shù)組只顯示為字符串,無論 tiny::xarray還是 tiny::xobject 都無法解析。后來就做了修改。

tiny::xarray arry; get_value(j, std::string("frist_reward_goods"), arry);

結(jié)果如下圖:

根據(jù)讀取結(jié)果,處理結(jié)果無法使用。數(shù)組元素讀取結(jié)果,把[]符號都加入進(jìn)去還是讀取很失敗。

修改如下:

/* 函數(shù)名:字符串切割子函數(shù) srcStr:源字符串 delimStr:分割符字符串 repeatedCharIgnored:是否支持分割符字符串合并 return:切割后的字符串Vector */ std::vector<std::string> splitString(std::string srcStr, std::string delimStr, bool repeatedCharIgnored) {std::vector<std::string> resultStringVector;std::replace_if(srcStr.begin(), srcStr.end(), [&](const char& c) {if (delimStr.find(c) != std::string::npos) { return true; } else { return false; }}/*pred*/, delimStr.at(0));//將出現(xiàn)的所有分隔符都替換成為一個(gè)相同的字符(分隔符字符串的第一個(gè))size_t pos = srcStr.find(delimStr.at(0));std::string addedString = "";while (pos != std::string::npos) {addedString = srcStr.substr(0, pos);if (!addedString.empty() || !repeatedCharIgnored) {resultStringVector.push_back(addedString);}srcStr.erase(srcStr.begin(), srcStr.begin() + pos + 1);pos = srcStr.find(delimStr.at(0));}addedString = srcStr;if (!addedString.empty() || !repeatedCharIgnored) {resultStringVector.push_back(addedString);}return resultStringVector; } /* 字符串?dāng)?shù)組獲取 in j:Json對象 int key:Json鍵值 output value 字符串?dāng)?shù)組 --利用 key,獲取數(shù)組字符串。'['數(shù)組元素的開始,'],'為一個(gè)字符串?dāng)?shù)組的結(jié)束。判斷'],'來劃分?jǐn)?shù)組。內(nèi)部以','來劃分,子相元素。 */ static void get_value(tiny::TinyJson j, std::string key, std::vector<std::vector<std::string>> &value){std::string object = j.Get<std::string>(key);int i = 1;while ( i < object.length() - 1){std::vector<std::string> item;if (object[i] == '['){std::string item_string;i++;while (object[i] != ']' && object[i] != '['){if (object[i] != ',' && object[i] != '"' && object[i] != ' '){item_string += object[i];}else if (object[i] == ',' || ( object[i] == '"'&& object[i+1] == ']')){item.push_back(item_string);item_string = "";}i++;}}if(!item.empty())value.push_back(item);i++;}}

處理結(jié)果如下所示:

std::vector<std::vector<std::string>> vec; get_value(j, std::string("frist_reward_goods"), vec);

3.相連Key和value的獲取

在實(shí)際使用中,發(fā)現(xiàn)相連的key和value如果相同,返回的value為下一個(gè)key值。

demo:type的值為cdk,cdk的值為18000002

"type\": \"cdk\",\"cdk\":\"18000002\" std::string cdk; get_value(j,std::string("cdk"),cdk);

處理結(jié)果如下圖:

原因:

原處理函數(shù)為:

template<typename R> R Get(std::string key, R defVal) {auto itr = std::find(KeyVal_.begin(), KeyVal_.end(), key);if (itr == KeyVal_.end()) {return defVal;}return Value(*(++itr)).GetAs<R>(); }

使用了std::find()方法,find的定義為返回第一個(gè)找到的元素。這里并沒有做返回的值是否為key還是value,所以出現(xiàn)了這個(gè)錯誤,修改如下,或元素的類型判斷。根據(jù)json key和value一一對應(yīng)的關(guān)系,可以判斷value為偶數(shù)為,從0開始計(jì)數(shù),value為奇數(shù)位。所以修改如下,手動遍歷。

template<typename R> R Get(std::string key, R defVal) {auto itr = KeyVal_.begin();int i = 0;for (itr; itr != KeyVal_.end(); itr++){if (key == (*itr) && !(i % 2))break;i++;}if (itr == KeyVal_.end()) {return defVal;}return Value(*(++itr)).GetAs<R>(); }

運(yùn)行結(jié)果如下:

cdk:18000002

封裝

頭文件調(diào)用

#include <iostream> #include <string> #include <vector> #include "tinyjson.hpp" //類的封裝 class Json { public:static tiny::TinyJson parse(std::string data){tiny::TinyJson json;json.ReadJson(data);return json;}static void get_value(tiny::TinyJson j, std::string key, std::string &value){value = j.Get<std::string>(key);}static void get_value(tiny::TinyJson j, std::string key, tiny::xarray &value){value = j.Get<tiny::xarray>(key);}static void get_value(tiny::TinyJson j, std::string key, std::vector<std::vector<std::string>> &value){std::string object = j.Get<std::string>(key);int i = 1;while ( i < object.length() - 1){std::vector<std::string> item;if (object[i] == '['){std::string item_string;i++;while (object[i] != ']' && object[i] != '['){if (object[i] != ',' && object[i] != '"' && object[i] != ' '){item_string += object[i];}else if (object[i] == ',' || ( object[i] == '"'&& object[i+1] == ']')){item.push_back(item_string);item_string = "";}i++;}}if(!item.empty())value.push_back(item);i++;}} private: };

模版函數(shù)

template<typename R> void get_value(tiny::TinyJson j, std::string key, R &value) {Json::get_value(j, key, value); }

使用:

//序列化 tiny::TinyJson j = Json::parse(data); //普通元素 std::string cdk; get_value(j,std::string("cdk"),cdk); //list數(shù)組元素 tiny::xarray arry; get_value(j, std::string("frist_reward_goods"), arry); //vector數(shù)組元素 std::vector<std::vector<std::string>> vec; get_value(j, std::string("frist_reward_goods"), vec);

其他

對TinyJson的再次封裝,使使用足夠方便。因?yàn)楸救酥皇褂媒馕?#xff0c;所以針對修改是針對TinyJson的解析修改。其他還需要其他人完善。

也可以將我上訴的元素再次封裝于tinyjson.hpp.獲取根據(jù)其他的使用再次封裝。

想著上傳合并到原作者的git分支,但是已經(jīng)有兩年沒有更新就沒有做。

如需源碼請留言。

總結(jié)

以上是生活随笔為你收集整理的C++轻量级Json解析工具—TinyJson的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。