Jsoncpp 在C++开发中的一些使用记录
jsoncpp 是一个C++ 语言实现的json库,非常方便得支持C++得各种数据类型到json 以及 json到各种数据类型的转化。
一个json 类型的数据如下:
{"code" : 10.01,"files" : "","msg" : "","uploadid" : "UP000000"
}
这种数据类型方便我们人阅读以及机器识别,因为将json类型的数据转化为机器可识别的二进制串的过程就是一个json语法解析的状态机状态迁移的过程,对计算机比较友好。
所以基本大多数的高级编程语言都有对应的json库,方便大家在大型项目中的数据传输以相同的数据类型进行交流。
这里可以看到其他语言的json库列表:https://www.json.org/json-en.html
使用jsoncpp的过程中经jsoncpp 作为项目的第三方库,并为需要使用json格式的头文件包含
json/json.h
即可。
Json 支持的数据类型
- signed integer [range: Value::minInt - Value::maxInt]
- unsigned integer (range: 0 - Value::maxUInt)
- double
- UTF-8 string
- boolean
- ‘null’
以及对应的字段转化为相应类型的接口:
std::string asString()Int asInt() const;UInt asUInt() const;
#if defined(JSON_HAS_INT64)Int64 asInt64() const;UInt64 asUInt64() const;
#endif // if defined(JSON_HAS_INT64)LargestInt asLargestInt() const;LargestUInt asLargestUInt() const;float asFloat() const;double asDouble() const;bool asBool() const;
Json 将字段解析为对应数据类型
如下方式进行json数据解析,并将解析出来的结果转化为相应的数据类型。
// 输入字符串形式的json串 转化为js_value的json 对象。
// 输入的buffer:
// std::string buffer = "{\"uploadid\": \"UP000000\",\"code\": 10.01,\"msg\": \"\",\"files\": \"\"}";
static void TestStringToJson(std::string buffer, Json::Value &js_value) {if (buffer.empty()) { return; } Json::Reader reader; if (reader.parse(buffer, js_value)) {// 将其中一个字段的数据转化为double类型。double res = js_value["code"].asDouble(); std::cout << "Finish parse string to double: " << res << std::endl;// 另一个字段的结果转化为string类型std::string upload = js_value["uploadid"].asString();std::cout << "Finish parse string: " << upload << std::endl;} else { std::cout << "Parse string to json failed!" << std::endl;}
}
最后的输出如下
Finish parse string to double: 10.01
Finish parse string: UP000000
从 std::map 生成Json 数据类型
这个过程就类似构造key-value一样,填充key,指定value即可。
如下函数:
inline void InitStatsMap() {AllStatsMap = {{1,10001},{2,20001},};
}std::map<uint64_t , std::string> StatsMap = {{1, "cpu.read.nanos"},{2, "cpu.write.nanos"}
};void TestJsonInsert() {Json::Value value;// 填充第一个字段的key 以及 对应的valuevalue["type"] = "kProfilingCPU";// 指定第二个字段"cpu"对应的key 的value也是一个json类型的字符串value["cpu"] = Json::objectValue;InitStatsMap();for (auto& pair: StatsMap) {value["cpu"][pair.second] = std::to_string(AllStatsMap[pair.first]);}std::cout << "Finish construct json form map : \n" << value << std::endl;
}
构建好的json 数据类型 输出如下:
{"cpu" : {"cpu.read.nanos" : "10001","cpu.write.nanos" : "20001"},"type" : "kProfilingCPU"
}
Json数据类型转化为string 数据类型
之前说过json支持的数据类型有string,同时也有这样的asString()
接口,但是这个接口仅仅是将json数据类型中的某一个key对应的field转化为string,比如前面的value["uploadid"]
对应的filed可以通过asString()
接口取到,作为string来直接使用。
但是我们想要将整个Json数据类型转化为string类型进行传输(http/restful 接口通信需要底层tcp需要传输char型的数据),则asString
接口无法满足,它需Json指定好对应的key才行。
jsoncpp支持如下两种方式:
第一种: 通过FastWriter 按照语法来解析json类型,转化为一个string
Json::FastWriter fast_writer;
std::string result = fast_writer.write(value);
std::cout << "json value: " << result << std::endl;
转化后的输出如下:
json value: {"cpu":{"cpu.read.nanos":"10001","cpu.write.nanos":"20001"},"type":"kProfilingCPU"}
第二种:通过value.toStyledString()
std::cout << "json value to string: " << value.toStyledString() << std::endl;
这种转化后的输出如下:
json value to string: {"cpu" : {"cpu.read.nanos" : "10001", "cpu.write.nanos" : "20001" }, "type" : "kProfilingCPU"
}
两种都会转化为string,只是最后的输出形式上 第二种会保持json本身的形态,每一个字段结束之后都会有一个换行符。
相应的两种writer的实现如下:
FastWriter::write
std::string FastWriter::write(const Value& root) {document_ = "";writeValue(root);if (!omitEndingLineFeed_)document_ += "\n";return document_;
}
StyledWriter::write
std::string StyledWriter::write(const Value& root) {document_ = "";addChildValues_ = false;indentString_ = "";writeCommentBeforeValue(root); // writeValue(root);writeCommentAfterValueOnSameLine(root);document_ += "\n";return document_;
}
讲一个未知的Json字符串解析为其他数据类型
前面描述的json数据类型转化为其他数据类型 其实都是我们知道json的一些field对应的key,所以我们可以通过value["xx"]
方式获取到所有的json数据。
但是实际使用过程中我们并不清楚传输过来的json字符串内容,所以需要能够直接将json的内容解析成为我们想要的格式。
这个时候我们可以通过jsonvalue提供的迭代器来做这件事情:
inline static void JsonToMap(std::string buffer,std::unordered_map<std::string, std::string>& options_map) {if (buffer.empty()) {return;}Json::Value root;Json::Reader reader;// Get the json's element and insert it into options_mapif (reader.parse(buffer, root)) {for (Json::Value::iterator element = root.begin();element != root.end(); element ++) {if (!element.key().empty()) {options_map.insert({element.key().asString(), (*element).asString()});}}}return;
}
完整测试代码
#include <stdio.h>
#include <string>
#include <unistd.h>#include <iostream>
#include <thread>
#include <cstring>
#include <unordered_map>
#include <map>#include "json/json.h"using namespace std;std::map<uint64_t , uint64_t> AllStatsMap;inline void InitStatsMap() {AllStatsMap = {{1,10001},{1,10002},{1,10003},{2,20001},{2,20002},{2,20003}};
}std::map<uint64_t , std::string> StatsMap = {{1, "cpu.read.nanos"},{2, "cpu.write.nanos"}
};void TestJsonInsert() {Json::Value value;value["type"] = "kProfilingCPU";value["cpu"] = Json::objectValue;InitStatsMap();for (auto& pair: StatsMap) {value["cpu"][pair.second] = std::to_string(AllStatsMap[pair.first]);}Json::FastWriter fast_writer;std::string result = fast_writer.write(value);std::cout << "json value: " << result << std::endl;std::cout << "json value to string: " << value.toStyledString() << std::endl;
}inline static void TestJsonToMap(std::string buffer,std::unordered_map<std::string, std::string>& options_map) {if (buffer.empty()) {return;}Json::Value root;Json::Reader reader;// Get the json's element and insert it into options.mapif (reader.parse(buffer, root)) {for (Json::Value::iterator element = root.begin();element != root.end(); element ++) {if (!element.key().empty()) {options_map.insert({element.key().asString(), (*element).asString()});}}}for (auto& op: options_map) {std::cout << op.first << " " << op.second << std::endl;}return;
}inline static void JsonToMap(std::string buffer,std::unordered_map<std::string, std::string>& options_map) {if (buffer.empty()) {return;}Json::Value root;Json::Reader reader;// Get the json's element and insert it into options.mapif (reader.parse(buffer, root)) {for (Json::Value::iterator element = root.begin();element != root.end(); element ++) {if (!element.key().empty()) {options_map.insert({element.key().asString(), (*element).asString()});}}}return;
}static void TestStringToJson(std::string buffer, Json::Value &js_value) {if (buffer.empty()) {return;}Json::Reader reader;if (reader.parse(buffer, js_value)) {std::cout << "Finish parse string to json: " << js_value << std::endl;std::string res = js_value["code"].asString();std::cout << "Finish parse string to double: " << res << std::endl;std::string upload = js_value["uploadid"].asString();std::cout << "Finish parse string: " << upload << std::endl;} else {std::cout << "Parse string to json failed!" << std::endl;}
}const std::string buffer = "{\"uploadid\": \"UP000000\",\"code\": 10.01,\"msg\": \"\",\"files\": \"\"}";
std::unordered_map<std::string, std::string> op_map;int main()
{TestJsonInsert();TestJsonToMap(buffer, op_map);Json::Value value;TestStringToJson(buffer, value);std::cout << "Json string to map with iterator : " << std::endl;std::unordered_map<std::string, std::string> mp;JsonToMap(buffer, mp);for (auto& pair : mp) {std::cout << pair.first << " " << pair.second << std::endl;}return 0;
}
Jsoncpp 在C++开发中的一些使用记录相关推荐
- 开发中Docker常用容器记录
开发中Docker常用容器记录 概览 分享工作学习中常用的Docker容器使用: 比如常用数据库的使用 消息队列类的使用 用于服务发现的容器使用 还有其他工作学习中使用到的 持续更新:https:// ...
- 德卡D3读卡器C#开发中的填坑记录
记录德卡D3读卡器的一些小坑.公司近期项目有IC卡的读写需求,买的是深圳德卡的D3U,开发语言用的是C#.帮助文档上写的动态类库函数与asp demo上有很大的区别,如果你也是用C#开发(Java d ...
- 开发中遇到的bug记录
1.启动类启动提示Mapper无法注入 启动来上注解 @MapperScan(basePackages = "com.xxx.xxx") 注意包路径 2.启动类启动提示dataso ...
- Unity个人开发中的踩坑记录(混沌式更新)
DateTime时间戳计算 一言蔽之,通常使用DateTime计算时间戳,起始时间点为UTC时间1970年1月1日0点整,需手动设置一个基准DateTime来处理. DateTime StartDat ...
- java ee有哪些工具_JavaEE开发中最常用到的技术和工具汇总
原标题:JavaEE开发中最常用到的技术和工具汇总 今天千锋广州小编给大家来介绍一下关于目前JavaEE开发中最常用到的技术和工具的介绍,下面我们一起来看一下吧. 项目管理:Ant,项目管理事实上的标 ...
- 分享.NET开发中经常使用到的代码片段 完全从实际项目中提取出来,也可被反反复复的重复借用...
几年前,一篇<ASP.NET开发人员经常使用的三十三种代码>非常流行,它总结了一些经常在ASP.NET开发中使用到的代码,直接可以拿来使用.今天重读这篇文章,有感而发,善于总结也是进步,于 ...
- 前端开发中的性能那点事
前端开发中的性能那点事(一)巧用xdebug 前言: 在我们平时的php开发中,一个大的项目经过长时间的积累以后你会发现性能越来越慢,而性能到底消耗在了什么地方,常常是一个令人头疼的问题,funct ...
- 开发中新游戏《庞加莱》
三体题材的游戏,表现三体人在三体星上生活和冒险. 收集水和物器,躲避火焰与巨日,探索遗迹并与巨型生物战斗. 温度会因太阳位置不同而发生变化,进而对环境产生一定影响. 游戏开发中. ---- 2017- ...
- Android安卓开发中图片缩放讲解
安卓开发中应用到图片的处理时候,我们通常会怎么缩放操作呢,来看下面的两种做法: 方法1:按固定比例进行缩放 在开发一些软件,如新闻客户端,很多时候要显示图片的缩略图,由于手机屏幕限制,一般情况下,我们 ...
最新文章
- 红旗linux桌面版反应慢,红旗Linux6.0桌面版使用感受
- HTML DOM Event 对象
- androidstudio mac mini_GitHub - jp1017/AndroidStudioPlugins: Android Studio 常用插件及浅释
- Linux配置静态IP地址
- C#调用C++函数来与串口通信
- frameset 后台管理_易达CMS下载-易达CMS(免费开源网站管理系统)v3.0.0.1103免费版
- micropython 串口写文件_MicroPython通过2G模块串口收发短信
- mq集群要建传输队列吗_面试官:消息队列这些我必问!
- 创建表的时候要添加目标语句use
- Java中的两种异常类型及其区别?
- 程序员经常去的编程教学视频网站
- arcgis for flex api version3.7 教程:7.使用Directions查询路线(最短路径分析)
- 我是火枪,我想打dps
- python识别字符串码置_python 字符串内置方法整理
- 8月第3周基金排行榜 | TokenInsight
- Could not inflate Behavior subclass
- 2020电赛芯片介绍和题目估计(二):LMT70
- DevOps入门系列--前瞻性--前瞻性思维
- python实用小工具
- oracle计算timestamp差,Oracle 计算timestamp和date类型的时间差
热门文章
- NET基础(3):is 和 as 操作符
- JAVA语法基础 3
- 图解DotNet框架系列
- win合适做服务器的系统,win系统做云服务器
- pacman 查询_pacman包管理常用命令
- php 5.4 iis6,WIN2003+IIS6+FastCGI+PHP5.4的安装配置
- python networkx教程_如何在python中使用networkx绘制有向图?
- Linux中锚定符号的作用,Linux基础(9)文本处理三剑客之grep
- 帝国cms 标签php,帝国cms常用标签总结
- java 类的执行顺序_java类加载的顺序