当前位置: 首页 > 编程日记 > 正文

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;
}

相关文章:

Java项目:图书管理系统(java+SSM+jsp+mysql+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 功能包括(管理员和学生角色)&#xff1a; 管理员和学生登录&#xff0c;图书管理&#xff0c;图书添加删除修改&#xff0c;图书 借阅&#xff0c;图书归还&#xff0c;图书查看&#xff0c;学…

使用 Flash Builder 的 Apple iOS 开发过程

使用 Flash Builder 的 Apple iOS 开发过程 iOS 开发和部署过程概述 构建、调试或部署 iOS 应用程序前的准备工作 在测试、调试或安装 iOS 应用程序时选择的文件 将应用程序部署到 Apple App Store 时选择的文件 在使用 Flash Builder 开发 iOS 应用程序之前&#xff0c;必须…

grep之字符串搜索算法Boyer-Moore由浅入深(比KMP快3-5倍)

2019独角兽企业重金招聘Python工程师标准>>> 1. 简单介绍 在用于查找子字符串的算法当中&#xff0c;BM&#xff08;Boyer-Moore&#xff09;算法是目前被认为最高效的字符串搜索算法&#xff0c;它由Bob Boyer和J Strother Moore设计于1977年。 一般情况下&#xf…

多线程threading

threading用于提供线程相关的操作&#xff0c;线程是应用程序中工作的最小单元。python当前版本的多线程库没有实现优先级、线程组&#xff0c;线程也不能被停止、暂停、恢复、中断。 1. threading模块提供的类&#xff1a; Thread, Lock, Rlock, Condition, [Bounded]Sem…

一个简单的程序来使用WiredTiger 存储引擎

前言 WiredTiger 自 mongodb3.0 集成进来之后为mongodb拉回了大量的口碑&#xff0c;从而在mongodb-3.2 版本直接代替了in-memory存储引擎&#xff0c;作为了mongodb的默认存储引擎。其 通过支持Append-only btree lsm-tree 以及 针对磁盘/内存数据结构上的多核和无锁优化&am…

Java项目:网上商城系统(java+SSM+jsp+mysql+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述功能 javaweb 网上商城系统&#xff0c;前台&#xff0b;后台管理&#xff0c;用户注册&#xff0c;登录&#xff0c;上哦展示&#xff0c;分组展示&#xff0c;搜索&#xff0c;收货地址管理&…

Linux 启动详解之init

1.init初探 init是Linux系统操作中不可缺少的程序之一。init进程&#xff0c;它是一个由内核启动的用户级进程&#xff0c;然后由它来启动后面的任务&#xff0c;包括多用户环境&#xff0c;网络等。 内核会在过去曾使用过init的几个地方查找它&#xff0c;它的正确位置&#x…

mysql 相关命令

mysqladmin versionmysqladmin statusmysqlshow -u帐号 -p密码 mysqlshow -u帐号 -p密码 库名mysql -u帐号 -p密码 -e SELECT Host,Db,User From db mysqlmysqldump --quick mysql | gzip > /root/mysql.gzmysqladmin create dbtestgunzip < /root/mysql.gz | mysql…

maven 添加数据库驱动

1.电脑上需要安装 apache maven2.下载oracle的jar包 例如我下载的是ojdbc7-12.jar3.cmd执行命令 mvn install:install-file -DgroupIdcom.oracle -DartifactIdojdbc7 -Dversion12 -Dpackagingjar -Dfiled:\jar\ojdbc7-12.jar-Dfile jar包所存放的位置4.pom文件添加&#xff1…

Rocksdb 的 BlobDB key-value 分离存储插件

前言 还是回到传统的 LSM-tree 中&#xff0c;我们key-value 写入时以append形态存放到一个data-block中&#xff0c;多个data-blockmetablock 之类的数据组织成一个sst。当我们读数据以及compaction的时候读到key 之后则很方便得读取到对应的value&#xff0c;一次I/O能够将k…

Java项目:(前端vue后台java微服务)在线考试系统(java+vue+springboot+mysql+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 考试流程&#xff1a; 用户前台注册成为学生 管理员后台添加老师&#xff0c;系统将该用户角色上升为老师 老师登录&#xff0c;添加考试,添加题目&#xff0c;发布考试 考生登录前台参加考试&#xff0c…

C++实现stack【栈】

要求&#xff1a; //****file: stack.h/*对stack进行初始化检查stack为空&#xff0c;或已满将整数压入到stack中从stack里弹出整数 不移除任何袁术&#xff0c;讲过stack的内容输出到标准输出Stack类的私有成员如下&#xff1a;一个用于打印错误信息的私有哦成员函数三个私有数…

c#操作Excel整理总结

大家好&#xff0c;这是我在工作中总结的关于C#操作Excel的帮助类&#xff0c;欢迎大家批评指正&#xff01; using System; using System.Collections.Generic; using System.Data; using System.Data.OleDb; using System.IO; using Aspose.Cells;namespace MusicgrabTool {p…

C++ std::function<void(int)> 和 std::function<void()> 作为函数参数的注意事项

前言 std::function 作为标准库提供的函数指针&#xff0c;使用起来还是比较方便的&#xff0c;不过在使用过程中有一些需要注意的细节&#xff0c;这里做一个简单的记录。 基本使用 头文件: #include <functional>语法&#xff1a;std::function<return_type(args…

Java项目:网上电商系统(java+SSM+mysql+maven+tomcat)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 功能&#xff1a;本系统分用户前台和管理员后台。 前台展示后台管理&#xff0c;前台界面可实现用户登录&#xff0c;用户注 册&#xff0c;商品展示&#xff0c;商品明细展示&#xff0c;用户…

C# SQLiteHelper

1 public class SQLiteHelpers2 {3 /// <summary> 4 /// ConnectionString样例&#xff1a;DatasourceTest.db3;Poolingtrue;FailIfMissingfalse 5 /// </summary> 6 public static string ConnectionStri…

[Git] 拉开发分支的代码报错

Git拉开发分支的代码报错&#xff1a; fatal: The remote end hung up unexpectedly fatal: early EOF fatal: index-pack failed 解决办法&#xff1a; git config --global core.compression -1 转载于:https://www.cnblogs.com/MasterMonkInTemple/p/10754596.html

C++ 通过模版工厂实现 简单反射机制

前言 我们知道Java/Python这种语言能够很好得 支持反射。反射机制 就是一种用户输入的字符串到对应实现方法的映射&#xff0c;比如http接口中 用户传入了url&#xff0c;我们需要调用该url对应的方法/函数对象 从而做出对应的操作。 而C 并没有友好得支持这样的操作&#xf…

计算机世界的“十六进制”为什么如此重要

在计算机世界中,十六进制扮演着不可或缺的角色。它以其紧凑的表示形式、与二进制的天然对应关系以及在各个领域的广泛应用,成为了计算机科学中的一把重要工具。总体而言,计算机需要十六进制并非偶然,它是一种为了更好地满足人类理解和处理数据的需求而产生的工具,为计算机科学的发展和应用提供了便利和支持。

面试官:如何实现10亿数据判重?

以 Java 中的 int 为例,来对比观察 BitMap 的优势,在 Java 中,int 类型通常需要 32 位(4 字节*8),而 BitMap 使用 1 位就可以来标识此元素是否存在,所以可以认为 BitMap 占用的空间大小,只有 int 类型的 1/32,所以有大数据量判重时,使用 BitMap 也可以实现。所以数据库去重显然是不行的。而使用集合也是不合适的,因为数据量太大,使用集合会导致内存不够用或内存溢出和 Full GC 频繁等问题,所以此时我们的解决方案通常是采用布隆过滤器来实现判重。

Java项目:校园二手市场系统(java+SSM+mysql+maven+tomcat)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述&#xff08; IW文档&#xff09; 功能&#xff1a;本系统分用户前台和管理员后台。 本系统用例模型有三种&#xff0c;分别是游客、注册用户和系统管 理员。下面分别对这三个角色的功能进行描…

php中$_REQUEST、$_POST、$_GET的区别和联系小结

php中$_REQUEST、$_POST、$_GET的区别和联系小结 作者&#xff1a; 字体&#xff1a;[增加 减小] 类型&#xff1a;转载php中有$_request与$_post、$_get用于接受表单数据&#xff0c;当时他们有何种区别&#xff0c;什么时候用那种最好。1. $_REQUEST php中$_REQUEST可以获取以…

uva 315 (poj 1144 求割点)

题意&#xff1a;给你一张无向图&#xff0c;求割点的个数。 思路&#xff1a;输入稍微处理一下接着直接套模版。 1 #include <iostream>2 #include <cstdio>3 #include <cstring>4 #include <cstdlib>5 #include <cmath>6 #include <algorit…

SQL学习之计算字段的用法与解析

一、计算字段 1、存储在数据库表中的数据一般不是应用程序所需要的格式。大多数情况下,数据表中的数据都需要进行二次处理。下面举几个例子。 (1)、我们需要一个字段同时显示公司名和公司地址&#xff0c;但这两个信息存储在不同表的列中。 (2)、省份、城市、邮政编码存储在不同…

手把手教你 用C++实现一个 可持久化 的http_server

前言 本文介绍一个有趣的 通过C实现的 持久化的http_server demo&#xff0c;这样我们通过http通信之后的数据可以持久化存储&#xff0c;即使server挂了&#xff0c;数据也不会丢失。我们的http_sever 也就能够真正得作为一个后端server了。 本身持久化这个能力是数据库提供…

【SVN多用户开发】代码冲突解决办法

SVN是一款集中式的代码存储工具&#xff0c;可以帮助多个用户协同开发同一应用程序。 但是SVN不能完全代替人工操作&#xff0c;有时也需要程序员自己进行沟通确认有效的代码。 下面就简单的看一下&#xff0c;常见的代码冲突以及解决方法。 总结起来&#xff0c;无非是&#x…

Java项目:在线宠物商店系统(java+SSM+mysql+maven+tomcat)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 功能&#xff1a;本系统分用户前台和管理员后台。 系统包括用户的注册登录&#xff0c;狗狗的展示购物车添加以及下 单支付购买&#xff0c;后台有管理员用户&#xff0c;可以操作狗狗的品种&…

字符串中的数字排序

2019独角兽企业重金招聘Python工程师标准>>> public static String getBusiScope(String busiScope){ String regex "\\d{1,2}"; String busiStr""; Pattern pattern Pattern.compile(regex); Matcher matcher pattern.matcher(busiScope…

oo第二单元总结

第二单元总结 第一次作业 一、设计策略 本次作业采用FAFS算法&#xff0c;可直接用输入线程与电梯线程交互&#xff0c;调度器暂时不需要参与&#xff0c;故一共设计三个类三线程&#xff1a;Main类、elevator类及input类&#xff0c;main线程、elevator线程及input线程。main线…

Rocksdb iterator 的 Forward-scan 和 Reverse-scan 的性能差异

前言 最近在读 MyRocks 存储引擎2020年的论文&#xff0c;因为这个存储引擎是在Rocksdb之上进行封装的&#xff0c;并且作为Facebook 内部MySQL的底层引擎&#xff0c;用来解决Innodb的空间利用率低下 和 压缩效率低下的问题。而且MyRocks 在接入他们UDB 之后成功达成了他们的…