• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            不會飛的鳥

            2010年12月10日 ... 不鳥他們!!! 我要用自己開發的分布式文件系統、分布式調度系統、分布式檢索系統, 做自己的搜索引擎!!!大魚有大志!!! ---楊書童

            [轉]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

            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

            {
                "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"
                            }
                        ]
                    }
                ]
            }
            解析代碼:
            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

                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

            // 轉換為字符串(帶格式)
            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

            解析一段下面的數據:

            {
              "code": 0,
              "images":
              [
                {
                  "url": "fmn057/20111221/1130/head_kJoO_05d9000251de125c.jpg"
                },
                {
                  "url": "fmn057/20111221/1130/original_kJoO_05d9000251de125c.jpg"
                }
              ]
            }
            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

            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,由于遇到問題太多只能換其它庫了。

            posted on 2014-05-26 00:36 不會飛的鳥 閱讀(939) 評論(0)  編輯 收藏 引用

            四虎影视久久久免费| 狠狠色噜噜狠狠狠狠狠色综合久久| 天天久久狠狠色综合| 99久久99久久精品国产| 午夜精品久久久久成人| 麻豆一区二区99久久久久| 久久青草国产精品一区| 中文成人久久久久影院免费观看 | 久久久久久精品无码人妻| 无码国产69精品久久久久网站| 99久久亚洲综合精品成人| 久久天天躁夜夜躁狠狠躁2022| 久久免费视频网站| 麻豆亚洲AV永久无码精品久久| 久久精品无码专区免费| 国产精品久久久久久吹潮| 四虎国产精品成人免费久久| 欧美亚洲另类久久综合| 青青草原精品99久久精品66| 欧美性大战久久久久久| 亚洲国产成人久久综合碰碰动漫3d| 精品久久久久久无码不卡| 日韩欧美亚洲综合久久影院Ds | 久久久久亚洲av无码专区导航| 久久精品国产精品亚洲艾草网美妙| 日产精品久久久久久久| 久久婷婷色综合一区二区| 久久中文精品无码中文字幕| 国产精品99久久不卡| 欧美综合天天夜夜久久| 久久99精品国产麻豆宅宅| 亚洲AV无码久久| 久久久久久亚洲Av无码精品专口 | 国内精品久久人妻互换| 久久国产高潮流白浆免费观看| 综合久久国产九一剧情麻豆| 久久天天躁狠狠躁夜夜2020一| 久久亚洲国产最新网站| 久久久久久久久久久久久久| av色综合久久天堂av色综合在| 久久无码专区国产精品发布|