Jsoncpp库使用
Json是一种轻量级的数据交换格式。Json组织形式就和C/C++中的map一样,是通过key-value对来组织的,key是任意一个唯一字符串,value可以是bool,int,string 或者嵌套的一个json。
Jsoncpp 是一个用来处理 Json文本的开源C++库。
一、jsoncpp交叉编译
1、cmake-gui图像界面
$ cd /home/tools/jsoncpp-1.8.0
$ mkdir build
$ cmake-gui
#------------图形界面操作-------------#
#where is the source code:/home/xfx/opensourcelib/jsoncpp-1.8.0 选择源码目录
#where to build the binaries:/home/xfx/opensourcelib/jsoncpp-1.8.0/build build目录
#点击configure
#选择specify options for cross-compliling,然后next
#target system--operating system :linux
#target system--processor:aarch64
#compilers--c:/usr/bin/aarch64-linux-gnu-gcc
#compilers--c++:/usr/bin/aarch64-linux-gnu-g++
#find program/library/include--target root:/usr/aarch64-linux-gnu,然后点击finish
#CMAKE_INSTALL_PREFIX xxx/xxx/xxx (想要安装的目录后面执行make install 的时候 编译好的库文件会安装到该目录 )
#选择好后点击Configure
#然后点击 Generate
#然后退出cmake-gui
#------------图形界面操作-------------end#
$ cd build
$ make
$ make install
2、命令行
$ cd jsoncpp-master && mkdir jsoncpp_build
$ cp -r include/ jsoncpp_build/ # include:后面所需要包含的头文件
$ cp src/lib_json/* jsoncpp_build/ # src/lib_josn:功能实现文件
#编译动态库
$ cd jsoncpp_build
$ source /home/pz/aarch64/set_xilinx_cross_compile.sh #加载交叉编译工具链
$ arm-linux-gueabihf-g++ -shared -fPIC *.cpp -I./include -o libjsoncpp.so
#shared:把对应的源文件形成对应的动态链接库。
#fPIC:用于生成位置无关的代码(Position-Independent-Code),代码在加载到内存时使用相对地址
#编译静态库
$ arm-linux-gueabihf-g++ -c *.cpp -I./include -fPIC
$ ar -cr libjsoncpp.a *.o #将所有目标文件.o合成一个库文件
二、Json::Reader
Json::Reader可以通过对Json字符串或者文件输入流进行解析,得到一个解析好的Json::Value。
bool parse (const std::string &document, Value &root, bool collectComments=true)
bool parse (std::istream &is, Value &root, bool collectComments=true)
//文件输入流解析,解析结果在root当中
void readJson(string& path, Json::Value& root)
{
std::ifstream ifs;
Json::Reader reader;
ifs.open(path);
if (!reader.parse(ifs, root, false)) {
ifs.close();
return;
}
if (ifs.is_open()){
ifs.close();
}
return;
}
//字符串解析
void readStrJson()
{
const char* str = "{\"name\":\"hahaha\",\"age\":\"21\",\"sex\":\"man\"}";
Json::Reader reader;
Json::Value root;
if (reader.parse(str, root)) {
string name = root["name"].asString();
int age = root["age"].asInt();
string sex = root["sex"].asString();
cout << name << "," << age << "," << sex << endl;
}
return;
}
三、Json::Writer
Json::Writer 和 Json::Reader相反,是把Json::Value对象写到string对象中,而且Json::Writer是个抽象类,被两个子类Json::FastWriter和Json::StyledWriter继承。FastWriter是无格式的写入,StyledWriter是带有格式的写入。
Json::Value root;
Json::Reader reader;
Json::FastWriter fwriter;
Json::StyledWriter swriter;
if(! reader.parse("example.json", root)){
return 0;
}
std::string str = fwriter(root);
std::ofstream ofs("example_fast_writer.json");
ofs << str;
ofs.close();
ofstream ofs("example_style_writer.json");
ofs << root.toStyledString();
ofs.close();
四、Json::Value
Json::Value 用来表示Json中的任何一种value抽象数据类型,具体来说,Json中的value可以是以下数据类型:
enum ValueType {
nullValue = 0, ///< 'null' value
intValue, ///< signed integer value
uintValue, ///< unsigned integer value
realValue, ///< double value
stringValue, ///< UTF-8 string value
booleanValue, ///< bool value
arrayValue, ///< array value (ordered list)
objectValue ///< object value (collection of name/value pairs).
};
1、增加元素
void add_json(){
string path = "123.json";
Json::Value root;
Json::FastWriter writer;
readJson(path, root);
//基本元素类型添加
root["name"] = "hahaha";
root["age"] = 52;
root["arr"].append("apple");
root["arr"].append("pear");
root["Id"] = Json::Value::Int(id);
root["Sn"] = Json::Value(sn);
root["data"]["mod"] = Json::Value::UInt64(256);
//arrayValue添加
Json::Value object;
Json::Value item;
item["name"] = "hehe";
item["ID"] = 2323;
object.append(item);
root["object"] = object;
//objectValue添加
Json::Value item1;
item1["name"] = "hehe";
item1["ID"] = 2323;
root["object1"] = item1;
string json = writer.write(root);
cout << json << endl;
}
//分别从两个数组中取一个值组成根节点下新的数组
int a[10] = { -1,-2,-3,-4,-5,-6,-7,-8,-9,0 };
int b[10] = { 1,2,3,4,5,6,7,8,9,0 };
Json::FastWriter writer;
Json::Value coorArr;
Json::Value iqArr;
for (int i = 0; i < 10; i++) {
iqArr[0] = a[i];
iqArr[1] = b[i];
coorArr[i] = iqArr;
}
root["coorArr"] = coorArr;
string sendstr = writer.write(root);
cout << sendstr << endl;
输出:
{
"Id" : 33444,
"Sn" : "202307201532",
"age" : 52,
"arr" : ["apple","pear"],
"coorArr" :
[
[-1,1],
[-2,2],
[-3,3],
[-4,4],
[-5,5],
[-6,6],
[-7,7],
[-8,8],
[-9,9],
[0,0]
],
"data" :{"mod" : 256},
"name" : "hahaha",
"object" :
[
{"ID" : 2323,"name" : "hehe"}
],
"object1" :
{
"ID" : 2323,
"name" : "hehe"
}
}
2、删除元素
//删除key为array_title数组下的key == value的数组元素
void delete_json(Json::Value& root, string key, string value, string array_title) {
/*创建新的数组排除掉匹配的数组元素*/
Json::Value newArray = Json::arrayValue;
int i = 0;
for (Json::ValueIterator itr_any = root[array_title].begin(); itr_any != root[array_title].end(); ++itr_any)
if (0 == _stricmp((*itr_any)[key].asString().c_str(), value.c_str()))
(*itr_any).clear();
else
newArray.append((*itr_any));
root[array_title] = newArray;
//写到本地文件
//ofstream ofs("123.json");
//ofs << root.toStyledString();
//ofs.close();
}
root.removeMember("dote"); //removeMember可删除根节点下key为dote的元素
3、修改元素
void update_json(Json::Value& root, string filename, string key, string value, string new_value) {
Json::Reader reader;
std::ifstream is;
is.open(filename, std::ios::binary);
if (reader.parse(is, root)) {
Json::Value::Members members = root.getMemberNames();
for (Json::Value::Members::iterator it = members.begin(); it != members.end(); it++){
Json::ValueType vt = root[*it].type();
switch (vt)
{
case Json::objectValue:{
int size = root[*it].size();
vector<string> sub_name = root[*it].getMemberNames();
for (unsigned int i = 0; i < sub_name.size(); ++i){
if (sub_name[i] == sub_key){
root[*it][sub_name[i]] = new_value;
}
}
}break;
case Json::stringValue:{
if (*it == sub_key) {
root[*it] = new_value;
}
}break;
case Json::arrayValue:{
for (unsigned int i = 0; i < root[*it].size(); i++){
if (root[*it][i][sub_key] == value) {
root[*it][i][sub_key] = new_value;
}
}
}break;
default:{
}break;
}
}
}
ofstream ofs(filename);
ofs << root.toStyledString();
ofs.close();
}
4、查找获取元素
//4.1动态获取根节点下key为poa_gain的键值对
vector<string> sub_name = root["poa_gain"].getMemberNames();
for (unsigned int i = 0; i < sub_name.size(); i++) {
cout << sub_name[i]<<":"<<root["poa_gain"][sub_name[i]]<< endl;
}
//4.2将json根节点下键值对转化为map存储
//stod()将string转化为double;dtos_self()函数将double转化为string类型;
string dtos_self(double i)
{
stringstream ss;
ss << i;
return ss.str();
}
map<double, double> json2map(const string& json)
{
Json::Reader reader;
Json::Value root;
map<double, double> maps;
if (json.length() > 0){
if (reader.parse(json, root)){
Json::Value::Members members = root.getMemberNames();
for (Json::Value::Members::iterator it = members.begin(); it != members.end(); it++){
Json::ValueType vt = root[*it].type();
switch (vt)
{
case Json::stringValue:{
maps.insert(pair<double, double>(stod(*it), stod(root[*it].asString())));
}break;
case Json::intValue:{
maps.insert(pair<double, double>(stod(*it), root[*it].asInt()));
}break;
case Json::realValue:{
maps.insert(pair<double, double>(stod(*it), root[*it].asDouble()));
}break;
default:{
}break;
}
}
}
}
return maps;
}
//4.3将map转化为json根节点下键值对存储
string map2json(const map<double, double>& map_info)
{
Json::Value root;
for (map<double, double>::const_iterator iter = map_info.begin(); iter != map_info.end(); ++iter){
root[iter->first] = iter->second;
}
return root.toStyledString();
}