1、jsoncpp库简单使用示例代码
在windows下使用cmake编译源码,版本为1.8.4。
#include<iostream>
#include <string>
#include <json/json.h> // 引用
/* 测试代码段1: 从json格式的字符串中解析读: */
int test1();
/* 测试代码段2: 将json对象的值输出: 包含格式化输出 */
int test2();
/* 测试代码段3: 从json格式的文件中解析读: */
#include <fstream>
#include <cassert> // 使用 assert断言,在linux下会出现core dumped ?
int test3();
/* 测试代码段4: 判断key是否存在, 是否为空 */
int test4();
/* 测试代码段5: 获取所有成员, 删除某个成员 */
int test5();
int main()
{
test1();
test2();
test3();
test4();
test5();
}
// 从json格式的字符串中解析读:
int test1()
{
std::string strjson = R"(
{
"key1":"value1",
"array":[
{"key2":"value2"},
{"key2":"value3"},
{"key2":"value4"}
]
}
)";
Json::Reader reader;
Json::Value root;
if (reader.parse(strjson, root))
{
std::string out = root["key1"].asString();
std::cout << out << std::endl;
const Json::Value arrayObj = root["array"];
for (int i = 0; i < arrayObj.size(); i++) // 这里的array包含 3个obj
{
//out = arrayObj[i]["key2"].asString(); // 确认知道是 string 类型
// 否则需要验证(其他数据类型类似)
if (arrayObj[i]["key2"].isString())
out = arrayObj[i]["key2"].asString();
std::cout << out << std::endl;
}
}
std::cout << std::endl;
return 0;
}
//将json对象的值输出: 包含格式化输出
int test2()
{
Json::Value root;
Json::Value arrayObj;
Json::Value item;
for (int i = 0; i < 10; i++){
item["key"] = i;
arrayObj.append(item);
}
root["key1"] = "value1"; //没有时会新增加
root["key2"] = "value2";
root["array"] = arrayObj;
//未格式化输出Json格式内容
Json::FastWriter writer;
std::string json_str = writer.write(root);
std::cout << json_str << std::endl;
// 格式化输出Json格式内容 1
Json::StyledWriter swriter;
json_str = swriter.write(root);
std::cout << json_str << std::endl;
// 格式化输出Json格式内容 2
std::string out = root.toStyledString();
std::cout << out << std::endl;
std::cout << "--------------------" << std::endl;
std::cout << std::endl;
return 0;
}
//从json格式的文件中解析读:
int test3()
{
/* test.json
{
"mmac": "e4:95:6e:4e:ed:6e",
"wmac": "ff:ff:ff:ff:ff:ff",
"data":
[ { "mac": "3c:46:d8:19:6a:e3", "rssi": "-82", "tmc": "ff:ff:ff:ff:ff:ff" },
{ "mac": "90:18:7c:f2:45:cc", "rssi": "-71", "tmc": "ff:ff:ff:ff:ff:ff" },
{ "mac": "b8:44:d9:02:b0:94", "rssi": "-86", "tmc": "ff:ff:ff:ff:ff:ff" },
{ "mac": "dc:85:de:6a:f8:37", "rssi": "-44", "tmc": "ff:ff:ff:ff:ff:ff" },
{ "mac": "ec:0e:c4:60:b7:95", "rssi": "-77", "tmc": "ff:ff:ff:ff:ff:ff" }
]
}
*/
std::ifstream ifs;
ifs.open("test.json");
assert(ifs.is_open());
Json::Reader reader;
Json::Value root;
if (!reader.parse(ifs, root, false)) {
std::cout << "reader.parse() fail" << std::endl;
return -1;
}
std::string out = root["mmac"].asString();
std::cout << "mmac " << out << std::endl;
out = root["wmac"].asString();
std::cout << "wmac " << out << std::endl;
const Json::Value arrayObj = root["data"];
for (int i = 0; i < arrayObj.size(); i++)
{
out = arrayObj[i]["mac"].asString();
std::cout << "data-->mac " << out << std::endl;
out = arrayObj[i]["rssi"].asString();
std::cout << "data-->rssi " << out << std::endl;
out = arrayObj[i]["tmc"].asString();
std::cout << "data-->tmc " << out << std::endl;
}
std::cout << std::endl;
return 0;
}
//判断key是否存在, 是否为空
int test4()
{
std::string strjson = R"(
{
"encoding" : "UTF-8",
"plug-ins" : [
"python",
"c++",
"ruby"
],
"indent" : {
"length" : 3,
"use_space": true
},
"tab-length":[],
"tab":null
}
)";
Json::Reader reader;
Json::Value root;
if (! reader.parse(strjson,root)) {
std::cerr << "apser error" << std::endl;
}
// 是否为成员,存在
if (root.isMember("encoding")) {
std::cout << "encoding is a member" << std::endl;
}else {
std::cout << "encoding is not a member" << std::endl;
}
if (root.isMember("encod")) {
std::cout << "encod is a member" << std::endl;
}else {
std::cout << "encod is not a member" << std::endl;
}
if (root.isMember("encod")) {
std::cout << "encod is a member" << std::endl;
}else {
std::cout << "encod is not a member" << std::endl;
}
// 键值是否为空 null
if (root["tab"].isNull()) {
std::cout << "isNull" << std::endl;//print isNull
}
if (root["newName"].isNull()) {
// 如果访问一个不存在的键,会自动创建,且键值为null. 这里用isNull时返回为真。
std::cout << "isNull" << std::endl;
}
// 总结就是要判断是否含有key,使用isMember成员函数,
// value是否为null使用isNull成员函数,value是否为空可以用empty() 和 size()成员函数。
std::cout << std::endl;
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
}
return 0;
}
// 获取所有成员, 删除某个成员
int test5()
{
std::string strjson = R"(
{
"encoding" : "UTF-8",
"plug-ins" : [
"python",
"c++",
"ruby"
],
"indent" : {
"length" : 3,
"use_space": true
},
"tab-length":[],
"tab":null
}
)";
Json::Reader reader;
Json::Value root;
if (!reader.parse(strjson, root)) {
std::cerr << "apser error" << std::endl;
}
Json::Value::Members members = root.getMemberNames(); //win32 typedef std::vector<std::string> Members;
for (auto& member : members)
std::cout << member << std::endl; // 所有的第一级 keyname
root.removeMember("tab-length"); // 删除某个成员
std::cout <<root.toStyledString() << std::endl;
return 0;
}
2、utf8 和本地多字符转换
网络上中文多采用utf8,直接解析可能出现乱码,需要解析。
Tip: string类型为utf-8转换为多字节string
auto UTF8ToString = [](const std::string& utf8Data){
//
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
std::wstring wString = conv.from_bytes(utf8Data); // utf-8 => wstring
std::wstring_convert<std::codecvt< wchar_t, char, std::mbstate_t>>
convert(new std::codecvt< wchar_t, char,std::mbstate_t>("CHS"));
std::string str = convert.to_bytes(wString); // wstring => string
return str;
};
3、CMakeLists.txt 项目文件配置
使用系统通过命令行安装,直接find_package即可。另外可以选择自己通过源码编译的静态库。
# jsoncpp
find_package(Jsoncpp QUIET)
if(NOT Jsoncpp_FOUND)
##### static library from source compling
find_package(PkgConfig)
set(ENV{PKG_CONFIG_PATH} "/home/hard_disk/wg/softwares/jsoncpp-1.8.4/install/lib/pkgconfig/")
pkg_search_module(Jsoncpp REQUIRED jsoncpp)
endif()
include_directories(${Jsoncpp_INCLUDE_DIRS}) # 'DIRS', not 'DIR'
link_directories(${Jsoncpp_LIBRARY_DIRS}) # pkg-config needed