• <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 不會飛的鳥 閱讀(925) 評論(0)  編輯 收藏 引用

            久久久久久久97| 久久乐国产综合亚洲精品| 久久久久人妻一区精品色| 久久亚洲私人国产精品| 国产L精品国产亚洲区久久| 久久一区二区免费播放| 久久精品aⅴ无码中文字字幕不卡| 成人资源影音先锋久久资源网| 久久精品成人一区二区三区| 久久久久久久波多野结衣高潮 | 日本久久久精品中文字幕| 精品水蜜桃久久久久久久| 久久久久se色偷偷亚洲精品av| 婷婷久久综合九色综合98| 久久午夜夜伦鲁鲁片免费无码影视 | 亚洲精品无码久久久久| 国产成人精品久久综合| 欧美精品久久久久久久自慰| 欧美亚洲日本久久精品| 国产精品99久久免费观看| 久久久久久久女国产乱让韩| 久久久精品人妻无码专区不卡| 99re久久精品国产首页2020| 久久国产劲爆AV内射—百度| 免费精品久久久久久中文字幕| 94久久国产乱子伦精品免费| 久久66热人妻偷产精品9| 99久久无色码中文字幕人妻| 欧美激情精品久久久久久久九九九 | 日韩精品无码久久久久久| 青青热久久国产久精品| 精品久久久久久无码免费| 久久免费线看线看| 久久777国产线看观看精品| 精品无码久久久久国产| 国产成人久久激情91| 久久发布国产伦子伦精品| 国产精品青草久久久久婷婷| 久久综合精品国产二区无码| 精品熟女少妇a∨免费久久| 人人狠狠综合久久88成人|