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++开发中的一些使用记录相关推荐

  1. 开发中Docker常用容器记录

    开发中Docker常用容器记录 概览 分享工作学习中常用的Docker容器使用: 比如常用数据库的使用 消息队列类的使用 用于服务发现的容器使用 还有其他工作学习中使用到的 持续更新:https:// ...

  2. 德卡D3读卡器C#开发中的填坑记录

    记录德卡D3读卡器的一些小坑.公司近期项目有IC卡的读写需求,买的是深圳德卡的D3U,开发语言用的是C#.帮助文档上写的动态类库函数与asp demo上有很大的区别,如果你也是用C#开发(Java d ...

  3. 开发中遇到的bug记录

    1.启动类启动提示Mapper无法注入 启动来上注解 @MapperScan(basePackages = "com.xxx.xxx") 注意包路径 2.启动类启动提示dataso ...

  4. Unity个人开发中的踩坑记录(混沌式更新)

    DateTime时间戳计算 一言蔽之,通常使用DateTime计算时间戳,起始时间点为UTC时间1970年1月1日0点整,需手动设置一个基准DateTime来处理. DateTime StartDat ...

  5. java ee有哪些工具_JavaEE开发中最常用到的技术和工具汇总

    原标题:JavaEE开发中最常用到的技术和工具汇总 今天千锋广州小编给大家来介绍一下关于目前JavaEE开发中最常用到的技术和工具的介绍,下面我们一起来看一下吧. 项目管理:Ant,项目管理事实上的标 ...

  6. 分享.NET开发中经常使用到的代码片段 完全从实际项目中提取出来,也可被反反复复的重复借用...

    几年前,一篇<ASP.NET开发人员经常使用的三十三种代码>非常流行,它总结了一些经常在ASP.NET开发中使用到的代码,直接可以拿来使用.今天重读这篇文章,有感而发,善于总结也是进步,于 ...

  7. 前端开发中的性能那点事

     前端开发中的性能那点事(一)巧用xdebug 前言: 在我们平时的php开发中,一个大的项目经过长时间的积累以后你会发现性能越来越慢,而性能到底消耗在了什么地方,常常是一个令人头疼的问题,funct ...

  8. 开发中新游戏《庞加莱》

    三体题材的游戏,表现三体人在三体星上生活和冒险. 收集水和物器,躲避火焰与巨日,探索遗迹并与巨型生物战斗. 温度会因太阳位置不同而发生变化,进而对环境产生一定影响. 游戏开发中. ---- 2017- ...

  9. Android安卓开发中图片缩放讲解

    安卓开发中应用到图片的处理时候,我们通常会怎么缩放操作呢,来看下面的两种做法: 方法1:按固定比例进行缩放 在开发一些软件,如新闻客户端,很多时候要显示图片的缩略图,由于手机屏幕限制,一般情况下,我们 ...

最新文章

  1. 红旗linux桌面版反应慢,红旗Linux6.0桌面版使用感受
  2. HTML DOM Event 对象
  3. androidstudio mac mini_GitHub - jp1017/AndroidStudioPlugins: Android Studio 常用插件及浅释
  4. Linux配置静态IP地址
  5. C#调用C++函数来与串口通信
  6. frameset 后台管理_易达CMS下载-易达CMS(免费开源网站管理系统)v3.0.0.1103免费版
  7. micropython 串口写文件_MicroPython通过2G模块串口收发短信
  8. mq集群要建传输队列吗_面试官:消息队列这些我必问!
  9. 创建表的时候要添加目标语句use
  10. Java中的两种异常类型及其区别?
  11. 程序员经常去的编程教学视频网站
  12. arcgis for flex api version3.7 教程:7.使用Directions查询路线(最短路径分析)
  13. 我是火枪,我想打dps
  14. python识别字符串码置_python 字符串内置方法整理
  15. 8月第3周基金排行榜 | TokenInsight
  16. Could not inflate Behavior subclass
  17. 2020电赛芯片介绍和题目估计(二):LMT70
  18. DevOps入门系列--前瞻性--前瞻性思维
  19. python实用小工具
  20. oracle计算timestamp差,Oracle 计算timestamp和date类型的时间差

热门文章

  1. NET基础(3):is 和 as 操作符
  2. JAVA语法基础 3
  3. 图解DotNet框架系列
  4. win合适做服务器的系统,win系统做云服务器
  5. pacman 查询_pacman包管理常用命令
  6. php 5.4 iis6,WIN2003+IIS6+FastCGI+PHP5.4的安装配置
  7. python networkx教程_如何在python中使用networkx绘制有向图?
  8. Linux中锚定符号的作用,Linux基础(9)文本处理三剑客之grep
  9. 帝国cms 标签php,帝国cms常用标签总结
  10. java 类的执行顺序_java类加载的顺序