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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++的Json解析库:jsoncpp和boost

發布時間:2024/4/11 c/c++ 70 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++的Json解析库:jsoncpp和boost 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JSON(JavaScript Object Notation)跟xml一樣也是一種數據交換格式,了解json請參考其官網http://json.org,本文不再對json做介紹,將重點介紹c++的json解析庫的使用方法。json官網上列出了各種語言對應的json解析庫,作者僅介紹自己使用過的兩種C++的json解析庫:jsoncpp(v0.5.0)和Boost(v1.34.0)。

?一. 使用jsoncpp解析json

Jsoncpp是個跨平臺的開源庫,首先從http://jsoncpp.sourceforge.net/上下載jsoncpp庫源碼,我下載的是v0.5.0,壓縮包大約107K,解壓,在jsoncpp-src-0.5.0/makefiles/vs71目錄里找到jsoncpp.sln,用VS2003及以上版本編譯,默認生成靜態鏈接庫。 在工程中引用,只需要include/json及.lib文件即可。

?使用JsonCpp前先來熟悉幾個主要的類:?

Json::Value ? ? 可以表示里所有的類型,比如int,string,object,array等,具體應用將會在后邊示例中介紹。

Json::Reader?? 將json文件流或字符串解析到Json::Value, 主要函數有Parse。

Json::Writer ? ?與Json::Reader相反,將Json::Value轉化成字符串流,注意它的兩個子類:Json::FastWriter和Json::StyleWriter,分別輸出不帶格式的json和帶格式的json。

?1. 從字符串解析json

[cpp]?view plaincopy
  • int?ParseJsonFromString()??
  • {??
  • ??const?char*?str?=?"{\"uploadid\":?\"UP000000\",\"code\":?100,\"msg\":?\"\",\"files\":?\"\"}";??
  • ??
  • ??Json::Reader?reader;??
  • ??Json::Value?root;??
  • ??if?(reader.parse(str,?root))??//?reader將Json字符串解析到root,root將包含Json里所有子元素??
  • ??{??
  • ????std::string?upload_id?=?root["uploadid"].asString();??//?訪問節點,upload_id?=?"UP000000"??
  • ????int?code?=?root["code"].asInt();????//?訪問節點,code?=?100??
  • ??}??
  • ??return?0;??
  • }??
  • 2. 從文件解析json

    json文件內容:

    [cpp]?view plaincopy
  • {??
  • ????"uploadid":?"UP000000",??
  • ????"code":?"0",??
  • ????"msg":?"",??
  • ????"files":??
  • ????[??
  • ????????{??
  • ????????????"code":?"0",??
  • ????????????"msg":?"",??
  • ????????????"filename":?"1D_16-35_1.jpg",??
  • ????????????"filesize":?"196690",??
  • ????????????"width":?"1024",??
  • ????????????"height":?"682",??
  • ????????????"images":??
  • ????????????[??
  • ????????????????{??
  • ????????????????????"url":?"fmn061/20111118",??
  • ????????????????????"type":?"large",??
  • ????????????????????"width":?"720",??
  • ????????????????????"height":?"479"??
  • ????????????????},??
  • ????????????????{??
  • ????????????????????"url":?"fmn061/20111118",??
  • ????????????????????"type":?"main",??
  • ????????????????????"width":?"200",??
  • ????????????????????"height":?"133"??
  • ????????????????}??
  • ????????????]??
  • ????????}??
  • ????]??
  • }??
  • ?解析代碼:

    [cpp]?view plaincopy
  • int?ParseJsonFromFile(const?char*?filename)??
  • {??
  • ??//?解析json用Json::Reader??
  • ??Json::Reader?reader;??
  • ??//?Json::Value是一種很重要的類型,可以代表任意類型。如int,?string,?object,?array...??
  • ??Json::Value?root;?????????
  • ??
  • ??std::ifstream?is;??
  • ??is.open?(filename,?std::ios::binary?);????
  • ??if?(reader.parse(is,?root))??
  • ??{??
  • ????std::string?code;??
  • ????if?(!root["files"].isNull())??//?訪問節點,Access?an?object?value?by?name,?create?a?null?member?if?it?does?not?exist.??
  • ??????code?=?root["uploadid"].asString();??
  • ??????
  • ????//?訪問節點,Return?the?member?named?key?if?it?exist,?defaultValue?otherwise.??
  • ????code?=?root.get("uploadid",?"null").asString();??
  • ??
  • ????//?得到"files"的數組個數??
  • ????int?file_size?=?root["files"].size();??
  • ??
  • ????//?遍歷數組??
  • ????for(int?i?=?0;?i?<?file_size;?++i)??
  • ????{??
  • ??????Json::Value?val_image?=?root["files"][i]["images"];??
  • ??????int?image_size?=?val_image.size();??
  • ??????for(int?j?=?0;?j?<?image_size;?++j)??
  • ??????{??
  • ????????std::string?type?=?val_image[j]["type"].asString();??
  • ????????std::string?url?=?val_image[j]["url"].asString();??
  • ??????}??
  • ????}??
  • ??}??
  • ??is.close();??
  • ??return?0;??
  • }??
  • ?3. 在json結構中插入json

    [cpp]?view plaincopy
  • Json::Value?arrayObj;???//?構建對象??
  • Json::Value?new_item,?new_item1;??
  • new_item["date"]?=?"2011-12-28";??
  • new_item1["time"]?=?"22:30:36";??
  • arrayObj.append(new_item);??//?插入數組成員??
  • arrayObj.append(new_item1);?//?插入數組成員??
  • int?file_size?=?root["files"].size();??
  • for(int?i?=?0;?i?<?file_size;?++i)??
  • ??root["files"][i]["exifs"]?=?arrayObj;???//?插入原json中??
  • ?4. 輸出json

    [cpp]?view plaincopy
  • //?轉換為字符串(帶格式)??
  • std::string?out?=?root.toStyledString();??
  • //?輸出無格式json字符串??
  • Json::FastWriter?writer;??
  • std::string?out2?=?writer.write(root);??
  • 二. 使用Boost property_tree解析json

    property_tree可以解析xml,json,ini,info等格式的數據,用property_tree解析這幾種格式使用方法很相似。

    解析json很簡單,命名空間為boost::property_tree,reson_json函數將文件流、字符串解析到ptree,write_json將ptree輸出為字符串或文件流。其余的都是對ptree的操作。

    解析json需要加頭文件:

    #include <boost/property_tree/ptree.hpp>
    #include <boost/property_tree/json_parser.hpp>

    1. 解析json

    解析一段下面的數據:

    [html]?view plaincopy
  • {??
  • ??"code":?0,??
  • ??"images":??
  • ??[??
  • ????{??
  • ??????"url":?"fmn057/20111221/1130/head_kJoO_05d9000251de125c.jpg"??
  • ????},??
  • ????{??
  • ??????"url":?"fmn057/20111221/1130/original_kJoO_05d9000251de125c.jpg"??
  • ????}??
  • ??]??
  • }??
  • [cpp]?view plaincopy
  • int?ParseJson()??
  • {??
  • ??std::string?str?=?"{\"code\":0,\"images\":[{\"url\":\"fmn057/20111221/1130/head_kJoO_05d9000251de125c.jpg\"},{\"url\":\"fmn057/20111221/1130/original_kJoO_05d9000251de125c.jpg\"}]}";??
  • ??using?namespace?boost::property_tree;??
  • ??
  • ??std::stringstream?ss(str);??
  • ??ptree?pt;??
  • ??try{??????
  • ????read_json(ss,?pt);??
  • ??}??
  • ??catch(ptree_error?&?e)?{??
  • ????return?1;???
  • ??}??
  • ??
  • ??try{??
  • ????int?code?=?pt.get<int>("code");???//?得到"code"的value??
  • ????ptree?image_array?=?pt.get_child("images");??//?get_child得到數組對象??
  • ??????
  • ????//?遍歷數組??
  • ????BOOST_FOREACH(boost::property_tree::ptree::value_type?&v,?image_array)??
  • ????{??
  • ??????std::stringstream?s;??
  • ??????write_json(s,?v.second);??
  • ??????std::string?image_item?=?s.str();??
  • ????}??
  • ??}??
  • ??catch?(ptree_error?&?e)??
  • ??{??
  • ????return?2;??
  • ??}??
  • ??return?0;??
  • }??
  • 2. 構造json

    [cpp]?view plaincopy
  • int?InsertJson()??
  • {??
  • ??std::string?str?=?"{\"code\":0,\"images\":[{\"url\":\"fmn057/20111221/1130/head_kJoO_05d9000251de125c.jpg\"},{\"url\":\"fmn057/20111221/1130/original_kJoO_05d9000251de125c.jpg\"}]}";??
  • ??using?namespace?boost::property_tree;??
  • ??
  • ??std::stringstream?ss(str);??
  • ??ptree?pt;??
  • ??try{??????
  • ????read_json(ss,?pt);??
  • ??}??
  • ??catch(ptree_error?&?e)?{??
  • ????return?1;???
  • ??}??
  • ??
  • ??//?修改/增加一個key-value,key不存在則增加??
  • ??pt.put("upid",?"00001");??
  • ??
  • ??//?插入一個數組??
  • ??ptree?exif_array;??
  • ??ptree?array1,?array2,?array3;??
  • ??array1.put("Make",?"NIKON");??
  • ??array2.put("DateTime",?"2011:05:31?06:47:09");??
  • ??array3.put("Software",?"Ver.1.01");??
  • ??exif_array.push_back(std::make_pair("",?array1));??
  • ??exif_array.push_back(std::make_pair("",?array2));??
  • ??exif_array.push_back(std::make_pair("",?array3));??
  • ??
  • //???exif_array.push_back(std::make_pair("Make",?"NIKON"));??
  • //???exif_array.push_back(std::make_pair("DateTime",?"2011:05:31?06:47:09"));??
  • //???exif_array.push_back(std::make_pair("Software",?"Ver.1.01"));??
  • ??
  • ??pt.put_child("exifs",?exif_array);??
  • ??std::stringstream?s2;??
  • ??write_json(s2,?pt);??
  • ??std::string?outstr?=?s2.str();??
  • ??
  • ??return?0;??
  • }??
  • ?

    三. 兩種解析庫的使用經驗

    1. 用boost::property_tree解析字符串遇到"\/"時解析失敗,而jsoncpp可以解析成功,要知道'/'前面加一個'\'是JSON標準格式。

    2. boost::property_tree的read_json和write_json在多線程中使用會引起崩潰。

    針對1,可以在使用boost::property_tree解析前寫個函數去掉"\/"中的'\',針對2,在多線程中同步一下可以解決。

    我的使用心得:使用boost::property_tree不僅可以解析json,還可以解析xml,info等格式的數據。對于解析json,使用boost::property_tree解析還可以忍受,但解析xml,由于遇到問題太多只能換其它庫了。

    ============================================================================================================

    JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式,和xml類似,本文主要對VS2008中使用Jsoncpp解析json的方法做一下記錄。
    Jsoncpp是個跨平臺的開源庫,下載地址:http://sourceforge.net/projects/jsoncpp/,我下載的是v0.5.0,壓縮包大約104K。

    方法一:使用Jsoncpp生成的lib文件
    ? ????解壓上面下載的Jsoncpp文件,在jsoncpp-src-0.5.0/makefiles/vs71目錄里找到jsoncpp.sln,用VS2008版本編譯,默認生成靜態鏈接庫。 在工程中引用,只需要包含include/json下的頭文件及生成的.lib文件即可。
    ? ????如何包含lib文件:在.cpp文件中#pragma comment(lib."json_vc71_libmt.lib"),在工程屬性中Linker下Input中Additional Dependencies寫入lib文件名字(Release下為json_vc71_libmt.lib,Debug為json_vc71_libmtd.lib

    注意:Jsoncpp的lib工程編譯選項要和VS工程中的編譯選項保持一致。如lib文件工程編譯選項為MT(或MTd),VS工程中也要選擇MT(或MTd),否則會出現編譯錯誤問題,debug和release下生成的lib文件名字不同,注意不要看錯了,當成一個文件來使用(我就犯了這個錯誤)。

    方法二:使用Jsoncpp包中的.cpp.h文件
    ? ????解壓上面下載的Jsoncpp文件,把jsoncpp-src-0.5.0文件拷貝到工程目錄下,jsoncpp-src-0.5.0\jsoncpp-src-0.5.0\include\jsonjsoncpp-src-0.5.0\jsoncpp-src-0.5.0\src\lib_json目錄里的文件包含到VS工程中,在VS工程的屬性C/C++下General中Additional Include Directories包含頭文件目錄.\jsoncpp-src-0.5.0\include。在使用的cpp文件中包含json頭文件即可,如:#include "json/json.h"。將json_reader.cpp、json_value.cpp和json_writer.cpp三個文件的Precompiled Header屬性設置為Not Using Precompiled Headers否則編譯會出現錯誤。

    jsoncpp 使用詳解

    jsoncpp 主要包含三種類型的 class:Value、Reader、Writer。jsoncpp 中所有對象、類名都在 namespace Json 中,包含 json.h 即可。

    Json::Value 只能處理 ANSI 類型的字符串,如果 C++ 程序是用 Unicode 編碼的,最好加一個 Adapt 類來適配。


    下面是從網上找的代碼示例:
    1. 從字符串解析json
    ? ??const?char*?str?=?"{\"uploadid\":?\"UP000000\",\"code\":?100,\"msg\":?\"\",\"files\":?\"\"}";??

    ????Json::Reader?reader;??
    ????Json::Value?root;??
    ????if?(reader.parse(str,?root))??//?reader將Json字符串解析到root,root將包含Json里所有子元素??
    ????{??
    ????????std::string?upload_id?=?root["uploadid"].asString();??//?訪問節點,upload_id?=?"UP000000"??
    ????????int?code?=?root["code"].asInt();????//?訪問節點,code?=?100?
    ????} ? 2. 從文件解析json
    int?ReadJsonFromFile(const?char*?filename)??
    {??
    ????Json::Reader?reader;//?解析json用Json::Reader???
    ????Json::Value?root;?//?Json::Value是一種很重要的類型,可以代表任意類型。如int,?string,?object,?array?????????

    ????std::ifstream?is;??
    ????is.open?(filename,?std::ios::binary?);????
    ????if?(reader.parse(is,?root,?FALSE))??
    ????{??
    ????????std::string?code;??
    ????????if?(!root["files"].isNull())??//?訪問節點,Access?an?object?value?by?name,?create?a?null?member?if?it?does?not?exist.??
    ????????????code?=?root["uploadid"].asString();??
    ????????
    ????????code?=?root.get("uploadid",?"null").asString();//?訪問節點,Return?the?member?named?key?if?it?exist,?defaultValue?otherwise.????

    ????????int?file_size?=?root["files"].size();??//?得到"files"的數組個數??
    ????????for(int?i?=?0;?i?<?file_size;?++i)??//?遍歷數組??
    ????????{??
    ????????????Json::Value?val_image?=?root["files"][i]["images"];??
    ????????????int?image_size?=?val_image.size();??
    ????????????for(int?j?=?0;?j?<?image_size;?++j)??
    ????????????{??
    ????????????????std::string?type?=?val_image[j]["type"].asString();??
    ????????????????std::string?url??=?val_image[j]["url"].asString();?
    ????????????????printf("type?:?%s,?url?:?%s?\n",?type.c_str(),?url.c_str());
    ????????????}??
    ????????}??
    ????}??
    ????is.close();??

    ????return?0;??
    }? 3. 向文件中插入json
    void?WriteJsonData(const?char*?filename)
    {
    ????Json::Reader?reader;??
    ????Json::Value?root;?//?Json::Value是一種很重要的類型,可以代表任意類型。如int,?string,?object,?array????????

    ????std::ifstream?is;??
    ????is.open?(filename,?std::ios::binary?);????
    ????if?(reader.parse(is,?root))??
    ????{??
    ????????Json::Value?arrayObj;???//?構建對象??
    ????????Json::Value?new_item,?new_item1;??
    ????????new_item["date"]?=?"2011-11-11";??
    ????????new_item1["time"]?=?"11:11:11";??
    ????????arrayObj.append(new_item);??//?插入數組成員??
    ????????arrayObj.append(new_item1);?//?插入數組成員??
    ????????int?file_size?=?root["files"].size();??
    ????????for(int?i?=?0;?i?<?file_size;?++i)??
    ????????????root["files"][i]["exifs"]?=?arrayObj;???//?插入原json中?
    ????????std::string?out?=?root.toStyledString();??
    ????????//?輸出無格式json字符串??
    ????????Json::FastWriter?writer;??
    ????????std::string?strWrite?=?writer.write(root);
    ????????std::ofstream?ofs;
    ????????ofs.open("test_write.json");
    ????????ofs?<<?strWrite;
    ????????ofs.close();
    ????}??

    ????is.close();??
    }
    下面是我寫的 使用 Jsoncpp生成lib文件的工程示例:Jsoncpp測試代碼,使用VS2008編譯通過。

    // TestJsoncppCode.cpp : Defines the entry point for the console application. //#include "stdafx.h" #include "TestJsoncppCode.h" #include "include/json/json.h" #include <fstream> #include <string>#pragma comment(lib."json_vc71_libmtd.lib")#ifdef _DEBUG #define new DEBUG_NEW #endif// The one and only application objectCWinApp theApp; using namespace std; CString GetWorkDir() { char pFileName[MAX_PATH]; int nPos = GetCurrentDirectory( MAX_PATH, pFileName); CString csFullPath(pFileName); if( nPos < 0 ) return CString(""); else return csFullPath; }void WriteJsonData(const char* filename) {Json::Reader reader; Json::Value root; // Json::Value是一種很重要的類型,可以代表任意類型。如int, string, object, array... std::ifstream is; is.open (filename, std::ios::binary ); if (reader.parse(is, root)) { Json::Value arrayObj; // 構建對象 Json::Value new_item, new_item1; new_item["date"] = "2011-11-11"; new_item1["time"] = "11:11:11"; arrayObj.append(new_item); // 插入數組成員 arrayObj.append(new_item1); // 插入數組成員 int file_size = root["files"].size(); for(int i = 0; i < file_size; ++i) root["files"][i]["exifs"] = arrayObj; // 插入原json中 std::string out = root.toStyledString(); // 輸出無格式json字符串 Json::FastWriter writer; std::string strWrite = writer.write(root);std::ofstream ofs;ofs.open("test_write.json");ofs << strWrite;ofs.close();} is.close(); }int ReadJsonFromFile(const char* filename) { Json::Reader reader;// 解析json用Json::Reader Json::Value root; // Json::Value是一種很重要的類型,可以代表任意類型。如int, string, object, array... std::ifstream is; is.open (filename, std::ios::binary ); if (reader.parse(is, root, FALSE)) { std::string code; if (!root["files"].isNull()) // 訪問節點,Access an object value by name, create a null member if it does not exist. code = root["uploadid"].asString(); code = root.get("uploadid", "null").asString();// 訪問節點,Return the member named key if it exist, defaultValue otherwise. int file_size = root["files"].size(); // 得到"files"的數組個數 for(int i = 0; i < file_size; ++i) // 遍歷數組 { Json::Value val_image = root["files"][i]["images"]; int image_size = val_image.size(); for(int j = 0; j < image_size; ++j) { std::string type = val_image[j]["type"].asString(); std::string url = val_image[j]["url"].asString(); printf("type : %s, url : %s \n", type.c_str(), url.c_str());} } } is.close(); return 0; } int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) {int nRetCode = 0;// initialize MFC and print and error on failureif (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)){// TODO: change error code to suit your needs_tprintf(_T("Fatal Error: MFC initialization failed\n"));nRetCode = 1;}else{// TODO: code your application's behavior here.}//1.從字符串解析jsonconst char* str = "{\"uploadid\": \"UP000000\",\"code\": 100,\"msg\": \"\",\"files\": \"\"}"; Json::Reader reader; Json::Value root; if (reader.parse(str, root)) // reader將Json字符串解析到root,root將包含Json里所有子元素 { printf("--------------從字符串讀取JSON---------------\n");std::string upload_id = root["uploadid"].asString(); // 訪問節點,upload_id = "UP000000" int code = root["code"].asInt(); // 訪問節點,code = 100 printf("upload_id : %s\ncode : %d \n", upload_id.c_str(), code);} //2.從文件解析jsonCString sTempPath = GetWorkDir() + "\\test_json.json";if (!CFileFind().FindFile(sTempPath)){printf("Not Find JSON File : %s", sTempPath);}else{printf("--------------從文件讀取JSON---------------\n");ReadJsonFromFile(sTempPath);}//3.向文件寫入jsonWriteJsonData(sTempPath);system("pause");return nRetCode; }

    總結

    以上是生活随笔為你收集整理的C++的Json解析库:jsoncpp和boost的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。