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.jsonif(!reader.parse(ifs, root)){// fail to parse
}
else{// successstd::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 failreturn 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": "Lihd@163.com","Hotmail": "Lihd@hotmail.com"}
}
void ReadJson(std::string filePath)
{ifstream is(filePath);JSONCPP_STRING errs;Json::Value root, lang, mail;Json::CharReaderBuilder readerBuilder;std::unique_ptr<Json::CharReader> 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: Lihd@163.com
Hotmail: Lihd@hotmail.com

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

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

#include <iostream>
#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"] = "Lihd@163.com";mail["Hotmail"] = "Lihd@hotmail.com";root["E-mail"] = mail;std::unique_ptr<Json::StreamWriter> 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" : "Lihd@hotmail.com","Netease" : "Lihd@163.com"},"Language" : ["C++","Java"],"Name" : "Lihd"
}

Jsoncpp 其他操作

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

判断key是否存在

bool Json::Value::isMember ( const char * key) constReturn 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")){//trueif(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 emptystd::cout << "empty: " << root["tab-length"].empty() << std::endl;//print empty: 1std::cout << "size: " << root["tab-length"].size() << std::endl;//print size: 0}

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

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

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

得到所有的key

typedef std::vector<std::string> Json::Value::MembersValue::Members Json::Value::getMemberNames ( ) constReturn a list of the member names.If null, return an empty list.Preconditiontype() is objectValue or nullValue Postconditionif 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.Returnsthe removed Value, or null. Preconditiontype() is objectValue or nullValue Postconditiontype() 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.Parameterskey may contain embedded nulls.Returnstrue 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;

Jsoncpp 使用说明相关推荐

  1. json-cpp使用笔记

    1. 介绍 Json-cpp是一个跨平台的轻量级的读取Json文件的C++开源库 2. 安装 可以自行下载编译安装 下载地址json-cpp download | SourceForge.net 也可 ...

  2. QtCreator动态编译jsoncpp完美支持x86和arm平台

    如果是做嵌入式开发. 在Qt下支持JSon最好的办法,可能不是采用qjson这个库.QJson这个库的实例只提供了x86环境下的编译方法. Installing QJson ------------- ...

  3. abaqus高性能服务器怎么用,高性能计算平台ABAQUS任务调度使用说明作者陈林E-Mailchenlin.PDF...

    高性能计算平台ABAQUS任务调度使用说明作者陈林E-Mailchenlin.PDF 高性能计算平台ABAQUS 任务调度使用说明 作者:陈林 E-Mail:chenlin@ 日期:2017-1-10 ...

  4. linux 文件拷贝并替换,Linux_cmd replace 文件替换使用说明,帮助信息: 复制代码 代码如 - phpStudy...

    cmd replace 文件替换使用说明 帮助信息: 复制代码 代码如下: 替换文件. REPLACE [drive1:][path1]filename [drive2:][path2] [/A] [ ...

  5. window环境Visual Studio配置:OpenCV,Eigen,jsoncpp

    OpenCV 一.计算机 中的配置: 在 计算机 -> 属性 -> 高级系统属性 -> 高级 -> 环境变量 -> 系统变量 -> Path 中添加: D:\Pro ...

  6. Jsoncpp 在C++开发中的一些使用记录

    jsoncpp 是一个C++ 语言实现的json库,非常方便得支持C++得各种数据类型到json 以及 json到各种数据类型的转化. 一个json 类型的数据如下: {"code" ...

  7. Simple Dynamic Strings(SDS)源码解析和使用说明二

    在<Simple Dynamic Strings(SDS)源码解析和使用说明一>文中,我们分析了SDS库中数据的基本结构和创建.释放等方法.本文将介绍其一些其他方法及实现.(转载请指明出于 ...

  8. C++简单使用Jsoncpp来读取写入json文件

    一.源码编译 C++操作json字符串最好的库应该就是jsoncpp了,开源并且跨平台.它可以从这里下载. 下载后将其解压到任意目录,它默认提供VS2003和VS2010的工程文件,使用VS2010可 ...

  9. Delphi开发的IOCP测试Demo以及使用说明。

    Delphi开发的IOCP,此为压力测试Demo和使用说明.

  10. Jsoncpp 使用方法解析

    Jsoncpp是目前比较好用的开源Json解析库,现在总结一下它的使用方法,理解,以供以后查阅. 在引入Jsoncpp的时候我们看到Jsoncpp里边的常用的cpp文件,有json_reader.cp ...

最新文章

  1. 10年磨一剑,软件编程走火入魔之:把简单的功能做个彻彻底底、把劳动成果重复利用...
  2. cad绘制椭圆的方法有几种_CAD新手入门教学:如何绘制矩形?
  3. webpackPlugin插件总结
  4. python调参工作都是干啥的_xgboost原理及调参方法-通俗易懂版本
  5. 有哪些命令行的软件堪称神器?
  6. linux adb 端口,linux 无法连接adb 设备
  7. 关于使用weex开发app上线App Store问题
  8. java ajax教程_JAVA AJAX教程第一章—初识AJAX
  9. 构造一个简单的Linux内核的MenuOS
  10. jsp定义java方法_jsp中java成员变量、方法的声明以及使用
  11. Python实现PDF转文字.
  12. axios在ie浏览器下提示promise未定义
  13. 如何停止Monkey测试
  14. postfix邮件服务器main.cf文件配置说明
  15. IP分片(一)【羊羊洒洒的Blog】
  16. CD网站用户消费行为的分析报告
  17. 能够研制超级计算机的国家,我国成为世界上第 个能够研制千万亿次超级计算机的国家.------ [ ] A.三 B.二 C.一 D.四...
  18. 彭于晏百度图片Ajax异步加载爬取
  19. 基于Spring Boot的学生志愿者管理系统的设计与实现
  20. 【问题集锦】【Jmeter】打开jmeter脚本时报如下错:problem loading XML from: CannotResolveClassException

热门文章

  1. 一些有意思的js代码
  2. creator创建密匙库,查询密匙库密匙,校对密匙
  3. 第一章 SpringMvc---Web MVC简介
  4. python --离线识别图片中文字(easyocr)
  5. Java第十九天:mysql(二)
  6. 集合例题3.:现在有一个map集合如下:Map<Integer,String> map = new HashMap<Integer, String>();map.put(1, “张三丰“);map.
  7. 单位旧计算机处理,单位出售旧电脑增值税税率是多少?
  8. springboot 返回二进制文件流
  9. 世界已进入第四次产业革命——大数据时代
  10. 信息可视化图表设计指南