Jsoncpp 使用说明

Json介绍

JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。通常用于数据交换或存储。

JsonCpp是一个基于C++语言的开源库,用于C++程序的Json数据的读写操作。

 

JsonCpp是一个开源库

下载地址:https://github.com/open-source-parsers/jsoncpp

文档地址:http://open-source-parsers.github.io/jsoncpp-docs/doxygen/index.html

 

使用方式

方式一: python脚本构件

官方提供的集成方案:https://github.com/open-source-parsers/jsoncpp/wiki/Amalgamated

其中最简单的方法是执行项目根目录中的python脚本,构建头文件和源文件。

1. 在安装Python环境的控制台中进入jsoncpp项目根目录,

2. 执行命令:

python amalgamate.py

3. 将生成的dist目录拷贝到自己的项目中,其中包源文件jsoncpp.cpp和头文件json.h、json-forwards.h

方式二: 使用静态库/动态库

官方推荐使用Ninja进行编译,项目说明里有介绍。当然也可以使用比较常用的cmake进行编译

mkdir -p build/debug
cd build/debug
cmake -DCMAKE_BUILD_TYPE=debug -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=ON -DARCHIVE_INSTALL_DIR=. -G "Unix Makefiles" ../..
make

生成的静/动态库文件目录为build/debug/src/lib_json/,使用的时候把include头文件加到工程中,链接使用-ljsoncpp参数指定链接库即可。

方式三: 使用源文件

相比使用静态库,我更倾向于直接使用源文件,感觉这样比较方便。
在项目目录中直接执行python amalgamate.py命令,会在dist目录下生成两个头文件和一个源文件json-forwards.h 、json.h和jsoncpp.cpp。因为jsoncpp源码就四五千行,直接放在jsconcpp.cpp中和工程中其他代码一起编译也比较方便。
 

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文件读写

旧API:

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<

使用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}}

使用旧API编译器有诸如下面的提醒,有点编译器会报warning,有的编译器会报error,

warning: 'Reader' is deprecated: Use CharReader and CharReaderBuilder instead [-Wdeprecated-declarations]

warning: 'FastWriter' is deprecated: Use StreamWriterBuilder instead [-Wdeprecated-declarations]

新API

CharReader:从字符串中读取Json数据的抽象类

CharReaderBuilder:CharReader类的实现,可以读取标准输入流中的数据

{
  "Name": "Lihd",
  "Age": 26,
  "Language": ["C++", "Java"],
  "E-mail": {
    "Netease": "[email protected]",
    "Hotmail": "[email protected]"
  }
}
void ReadJson(std::string filePath)
{
    ifstream is(filePath);
    JSONCPP_STRING errs;
    Json::Value root, lang, mail;
    Json::CharReaderBuilder readerBuilder;

    std::unique_ptr const jsonReader(readerBuilder.newCharReader());
    bool res = parseFromStream(readerBuilder, &root, &errs);
    if (!res || !errs.empty()) {
        std::cout << "parseJson err. " << errs << std::endl;
    }

    std::cout << "Name: " << root["Name"].asString() << std::endl;
    std::cout << "Age: " << root["Age"].asInt() << std::endl;

    lang = root["Language"];
    std::cout << "Language: ";
    for (int i = 0; i < lang.size(); ++i) {
        std::cout << lang[i] << " ";
    }
    std::cout << std::endl;

    mail = root["E-mail"];
    std::cout << "Netease: " << mail["Netease"].asString() << std::endl;
    std::cout << "Hotmail: " << mail["Hotmail"].asString() << std::endl;
}

在main函数里面调用这个函数,以上一个函数的返回值作为输入参数会有如下输出:

Name: Lihd
Age: 26
Language: "C++" "Java" 
Netease: [email protected]
Hotmail: [email protected]

StreamWriter:从字符串中谁出到Json文件

StreamWriterBuilder:StreamWriter类的实现,可以输出Json格式数据

#include 
#include "json/json.h"

std::string createJson()
{
    std::string jsonStr;
    Json::Value root, lang, mail;
    Json::StreamWriterBuilder writerBuilder;
    std::ostringstream os;

    root["Name"] = "Lihd";
    root["Age"] = 26;

    lang[0] = "C++";
    lang[1] = "Java";
    root["Language"] = lang;

    mail["Netease"] = "[email protected]";
    mail["Hotmail"] = "[email protected]";
    root["E-mail"] = mail;

    std::unique_ptr jsonWriter(writerBuilder.newStreamWriter());
    jsonWriter->write(root, &os);
    jsonStr = os.str();

    std::cout << "Json:\n" << jsonStr << std::endl;
    return jsonStr;
}

调用这个函数会输出

Json:
{
	"Age" : 26,
	"E-mail" : 
	{
		"Hotmail" : "[email protected]",
		"Netease" : "[email protected]"
	},
	"Language" : 
	[
		"C++",
		"Java"
	],
	"Name" : "Lihd"
}

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

判断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" <
if(root.isMember("tab-length")){//true
    if(root["tab-length"].isNull()){
      std::cout << "isNull" << std::endl;
    }
    else std::cout << "not Null"<

另外值得强调的是,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 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) 

Json::Value其他的成员函数还有

// 转换类型
Int asInt() const;
UInt asUInt() const;
Int64 asInt64() const;
UInt64 asUInt64() const;
LargestInt asLargestInt() const;
LargestUInt asLargestUInt() const;
float asFloat() const;
double asDouble() const;
bool asBool() const;
// 检测类型
bool isNull() const;
bool isBool() const;
bool isInt() const;
bool isInt64() const;
bool isUInt() const;
bool isUInt64() const;
bool isIntegral() const;
bool isDouble() const;
bool isNumeric() const;
bool isString() const;
bool isArray() const;
bool isObject() const;

 

你可能感兴趣的:(C++)