jsoncpp配置与使用

C++要使用JSON来解析数据,一般采用jsoncpp.

配置

下载jsoncpp后,按ReadMe文档的说法是要先安装的,但是安装比较麻烦。然而事实上,我们并不需要安装,就可以直接使用。

方法一:直接拷贝源文件。这个方法比较简单,但不推荐,因为不便于项目管理。

  1. VS2008里新建一个空的控制台程序(用作测试jsoncpp是否可用),名为: TestJSON
  2. 解压下载好的文件:jsoncpp-src-0.5.0.tar.gz
  3. 将 jsoncpp-src-0.5.0\include 目录下的json文件夹拷贝至 TestJSON 工程目录下
  4. 将 jsoncpp-src-0.5.0\src\lib_json 目录下的所有.h, .cpp 文件以及json_valueiterator,  json_internalarray,  json_internalmap全部拷贝至 TestJSON 工程目录下
  5. 在VS2008里引入工程目录下刚刚从 jsoncpp-src-0.5.0 导入的文件,如图1
  6. 在VS2008里新建main.cpp来测试jsoncpp是否可用。代码见文章末尾main.cpp
  7. 在调试过程中会遇到一些错误,相应改之即可:
  8. json_reader.cpp 中加入#include "stdafx.h",将#include<json/reader.h>改为#include“json/reader.h”,#include<json/value.h>改为#include "json/value.h";
  9. json_value.cpp中加入#include "stdafx.h",将#include <json/value.h>改为#include "json/value.h", #include <json/writer.h>改为 #include "json/writer.h";
  10. json_writer.cpp中加入#include "stdafx.h",将#include <json/writer.h>改为#include "json/writer.h"。

方法二:使用静态链接库

  1. VS2008里新建一个空的控制台程序(用作测试jsoncpp是否可用),名为: TestJSON
  2. 解压下载好的文件:jsoncpp-src-0.5.0.tar.gz
  3. 利用VS2008打开jsoncpp-src-0.5.0\makefiles\vs71目录下的jsoncpp.sln,会出现三个Project:jsontest, lib_json, test_lib_json
  4. 在lib_json上 右击-->Properties-->Configuration Properties-->C/C++-->Code Generation,注意右侧的Runtime Library的内容,如图2,看完箭头所指的东西就可以点确定,关掉属性页。
  5. 编译lib_json,显示编译成功后,在jsoncpp-src-0.5.0\build\vs71\debug\lib_json目录下会生成一个json_vc71_libmtd.lib,将这个lib拷贝至TestJSON工程目录下。
  6. 将jsoncpp-src-0.5.0\include\json目录下的所有.h文件拷贝至TestJSON工程目录下,并在工程Header Files引入.
  7. 将方法一里的main.cpp添加到工程中,并在工程名上 右击-->Properties-->Configuration Properties-->C/C++-->Code Generation, 将Runtime Library改成图2箭头所示内容。
  8. 在工程名上 右击-->Properties-->Configuration Properties-->Linker-->Input, 在Additional Dependencies里填写json_vc71_libmtd.lib,然后确定,编译就行了。

使用

Jsoncpp 常用变量介绍

在Jsoncpp中,有几个常用的变量特别重要,首先介绍一下。

Json::Value

Json::Value 用来表示Json中的任何一种value抽象数据类型,具体来说,Json中的value可以是一下数据类型:

  • 有符号整数 signed integer [range: Value::minInt - Value::maxInt]
  • 无符号整数 unsigned integer (range: 0 - Value::maxUInt)
  • 双精度浮点数 double
  • 字符串 UTF-8 string
  • 布尔型 boolean
  • 空 ‘null’
  • 一个Value的有序列表 an ordered list of Value
  • collection of name/value pairs (javascript object)

可以通过[]的方法来取值。

//Examples:
Json::Value null_value; // null
Json::Value arr_value(Json::arrayValue); // []
Json::Value obj_value(Json::objectValue); // {}

 

Json::Reader介绍

Json::Reader

Json::Reader可以通过对Json源目标进行解析,得到一个解析好了的Json::Value,通常字符串或者文件输入流可以作为源目标。

假设现在有一个example.json文件

{
    "encoding" : "UTF-8",
    "plug-ins" : [
        "python",
        "c++",
        "ruby"
        ],
    "indent" : { "length" : 3, "use_space": true }
}

 

使用Json::Reader对Json文件进行解析:

bool parse (const std::string &document, Value &root, bool collectComments=true)
bool parse (std::istream &is, Value &root, bool collectComments=true)

 


Json::Value root;
Json::Reader reader;
std::ifstream ifs("example.json");//open file example.json

if(!reader.parse(ifs, root)){
   // fail to parse
}
else{
   // success
   std::cout<<root["encoding"].asString()<<endl;
   std::cout<<root["indent"]["length"].asInt()<<endl;
}

 

使用Json::Reader对字符串进行解析

bool Json::Reader::parse ( const char * beginDoc,
        const char * endDoc,
        Value & root,
        bool collectComments = true 
    )   

 

  Json::Value root;
  Json::Reader reader;
  const char* s = "{\"uploadid\": \"UP000000\",\"code\": 100,\"msg\": \"\",\"files\": \"\"}"; 
  if(!reader.parse(s, root)){
    // "parse fail";
  }
  else{
      std::cout << root["uploadid"].asString();//print "UP000000"
  }

 

Json::Writer介绍

Json::Writer 和 Json::Reader相反,是把Json::Value对象写到string对象中,而且Json::Writer是个抽象类,被两个子类Json::FastWriter和Json::StyledWriter继承。 
简单来说FastWriter就是无格式的写入,这样的Json看起来很乱没有格式,而StyledWriter就是带有格式的写入,看起来会比较友好。

Json::Value root;
Json::Reader reader;
Json::FastWriter fwriter;
Json::StyledWriter swriter;

if(! reader.parse("example.json", root)){
// parse fail
    return 0;
}
std::string str = fwriter(root);
std::ofstream ofs("example_fast_writer.json");
ofs << str;
ofs.close();

str = swriter(root);
ofs.open("example_styled_writer.json");
ofs << str;
ofs.close();

 

结果: 
example_styled_writer.json

{
    "encoding" : "UTF-8",
    "plug-ins" : [
        "python",
        "c++",
        "ruby"
        ],
    "indent" : { "length" : 3, "use_space": true }
}

 

example_fast_writer.json

{"encoding" : "UTF-8","plug-ins" : ["python","c++","ruby"],"indent" : { "length" : 3, "use_space": true}}

 


Jsoncpp 其他操作

通过前面介绍的Json::value, Json::Reader, Json::Reader 可以实现对Json文件的基本操作,下面介绍一些其他的常用的操作。

判断key是否存在

bool Json::Value::isMember ( const char * key) const

Return true if the object has a member named key.

Note
    'key' must be null-terminated. 

bool Json::Value::isMember ( const std::string &  key) const
bool Json::Value::isMember ( const char* key, const char * end ) const

 

// print "encoding is a member"
if(root.isMember("encoding")){
    std::cout<<"encoding is a member"<<std::endl;
}
else{
    std::cout<<"encoding is not a member"<<std::endl;
}

// print "encode is not a member"
if(root.isMember("encode")){
    std::cout<<"encode is a member"<<std::endl;
}
else{
    std::cout<<"encode is not a member"<<std::endl;
}

 

 

判断Value是否为null

首先要给example.json添加一个key-value对:

{
    "encoding" : "UTF-8",
    "plug-ins" : [
        "python",
        "c++",
        "ruby"
    ],
    "indent" : { "length" : 3, "use_space": true },
    "tab-length":[],
    "tab":null
}

 

判断是否为null的成员函数

bool Json::Value::isNull ( ) const
if(root["tab"].isNull()){
    std::cout << "isNull" <<std::endl;//print isNull
}

 

if(root.isMember("tab-length")){//true
    if(root["tab-length"].isNull()){
      std::cout << "isNull" << std::endl;
    }
    else std::cout << "not Null"<<std::endl;
    // print "not Null", there is a array object([]), through this array object is empty
    std::cout << "empty: " << root["tab-length"].empty() << std::endl;//print empty: 1
    std::cout << "size: " << root["tab-length"].size() << std::endl;//print size: 0
  }

 

另外值得强调的是,Json::Value和C++中的map有一个共同的特点,就是当你尝试访问一个不存在的 key 时,会自动生成这样一个key-value默认为null的值对。也就是说

 root["anything-not-exist"].isNull(); //false
 root.isMember("anything-not-exist"); //true

 

总结就是要判断是否含有key,使用isMember成员函数,value是否为null使用isNull成员函数,value是否为空可以用empty() 和 size()成员函数。

 

得到所有的key

typedef std::vector<std::string> Json::Value::Members

Value::Members Json::Value::getMemberNames ( ) const

Return a list of the member names.

If null, return an empty list.

Precondition
    type() is objectValue or nullValue 

Postcondition
    if type() was nullValue, it remains nullValue 

 

可以看到Json::Value::Members实际上就是一个值为string的vector,通过getMemberNames得到所有的key。

 

删除成员

Value Json::Value::removeMember( const char* key)   

Remove and return the named member.
Do nothing if it did not exist.

Returns
    the removed Value, or null. 

Precondition
    type() is objectValue or nullValue 

Postcondition
    type() is unchanged 

Value Json::Value::removeMember( const std::string & key)   

bool Json::Value::removeMember( std::string const &key, Value *removed)         

Remove the named map member.
Update 'removed' iff removed.

Parameters
    key may contain embedded nulls.

Returns
    true iff removed (no exceptions) 

merge 操作

     Json::Value colony_value1;
     if (!str_colony1.empty())
     {
         if(!reader.parse(str_colony1, colony_value))
         {
             //log err
         }
     }
 
     if (!str_group1.empty())
     {
         bool is_success = false;
         Json::Value group_value;
         is_success = reader.parse(str_group1, group_value);
 
         if (is_success)
         {
             Json::Value::Members members;
 
             members = group_value.getMemberNames();
             for (Json::Value::Members::iterator it = members.begin(); it != members.end(); ++it)
             {
                 colony_value[*it] = group_value[*it];
             }
         }
     }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值