c++解析json

 
 

一、简单介绍

  JSON 的全称为:JavaScript Object Notation,JSON 是用于标记 Javascript 对象的,JSON 官方的解释为:JSON 是一种轻量级的数据传输格式。

二、第三方库

  jsoncpp:它 是比较出名的 C++ JSON 解析库。地址:http://sourceforge.net/projects/jsoncpp

三、使用方法

  jsoncpp 主要包含三个class:Value、Reader、Writer。jsoncpp 中所有对象、类名都在 namespace Json 中,只需要包含 json.h 即可。注意Json::Value 只能处理 ANSI 类型的字符串,如果 C++ 程序是用 Unicode 编码的,最好加一个 Adapt 类来适配。

  1.Json::Value     可以表示里所有的类型,比如int,string,object,array等。

Json::Value使用 Json::Value json_temp;     

// 临时对象,供如下代码使用 json_temp["name"] = Json::Value("huchao");

json_temp["age"] = Json::Value(26);

Json::Value root;                    // 表示整个 json 对象

root["key_string"] = Json::Value("value_string");     // 新建一个 Key(名为:key_string),赋予字符串值:"value_string"。

root["key_number"] = Json::Value(12345);             // 新建一个 Key(名为:key_number),赋予数值:12345。

root["key_boolean"] = Json::Value(false);             // 新建一个 Key(名为:key_boolean),赋予bool值:false。

root["key_double"] = Json::Value(12.345);             // 新建一个 Key(名为:key_double),赋予 double 值:12.345。

root["key_object"] = Json_temp;                       // 新建一个 Key(名为:key_object),赋予 json::Value 对象值。

root["key_array"].append("array_string");             // 新建一个 Key(名为:key_array),类型为数组,对第一个元素赋值为字符串:"array_string"。

root["key_array"].append(1234);                       // 为数组 key_array 赋值,对第二个元素赋值为:1234。

Json::ValueType type = root.type();                   // 获得 root 的类型,此处为 objectValue 类型。

注:跟C++ 不同,JavaScript 数组可以为任意类型的值,所以 jsoncpp 也可以。 如上几个用法已经可以满足绝大部分 json 应用了,当然 jsoncpp 还有一些其他用法,比如说设置注释、比较 json 大小、交换 json 对象等。

  2.Json::Reader   将json文件流或字符串解析到Json::Value, 主要函数有Parse。

查看 json 内容,使用 Writer 类即可。

Jsoncpp 的 Json::Writer 类是一个纯虚类,并不能直接使用。在此我们使用 Json::Writer 的子类:Json::FastWriter、Json::StyledWriter、Json::StyledStreamWriter。 Json::FastWriter fast_writer;

std::cout << fast_writer.write(root) << std::endl;

输出结果为: {"key_array":["array_string",1234],"key_boolean":false,"key_double":12.3450,"key_number":12345,"key_object":{"age":26,"name":"name1"},"key_string":"value_string"}

用 Json::StyledWriter 是格式化后的 json,下面我们来看看 Json::StyledWriter 是怎样格式化的。

Json::StyledWriter styled_writer; std::cout << styled_writer.write(root) << std::endl; 输出结果为:

{    "key_array" : [ "array_string", 1234 ],    "key_boolean" : false,    "key_double" : 12.3450,    "key_number" : 12345,    "key_object" : {       "age" : 26,       "name" : "name1"    },    "key_string" : "value_string" }

 

  3.Json::Writer    与Json::Reader相反,将Json::Value转化成字符串流,注意它的两个子类:Json::FastWriter和Json::StyleWriter,分别输出不带格式的json和带格式的json。

Json::Reader 是用于读取的,用于将字符串转换为 Json::Value 对象的,   Json::Reader reader;  

Json::Value json_object;  

const char* json_document = "{\"age\" : 26,\"name\" : \"123\"}";  

if (!reader.parse(json_document, json_object))     return 0;  

std::cout << json_object["name"] << std::endl;  

std::cout << json_object["age"] << std::endl;

输出结果为: "123"

例如:

字符串方式:

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;    

}  

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;  
}

从文件解析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"    

                }    

            ]    

        }    

    ]    

}    

{  
    "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;    

}    

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;  
}  

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中   

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中 

输出Json

// 转换为字符串(带格式)      

std::string out = root.toStyledString();    

// 输出无格式json字符串      

Json::FastWriter writer;    

std::string out2 = writer.write(root);    

// 转换为字符串(带格式)   
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

  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();  
}

 

posted @ 2016-11-30 15:17  卖雨伞的小男孩  阅读(1337)  评论(0编辑  收藏  举报