json11库的使用

2023-11-11

JSON(JavaScript Object Notation)是一种轻量级的文本数据交换格式,易于让人阅读。同时也易于机器解析和生成。尽管JSON是Javascript的一个子集,但JSON是独立于语言的文本格式,并且采用了类似于C语言家族的一些习惯。JSON解析器和JSON库支持许多不同的编程语言。

几乎所有与网页开发相关的语言都有JSON库。JSON比XML更小、更快。

JSON用于描述数据结构,有以下形式存在:

(1)、对象(object):一个对象以”{“开始,并以”}”结束。一个对象包含一系列非排序的名称/值对,每个名称/值对之间使用”,”分隔。

(2)、名称/值(collection):名称和值之间使用”:”隔开。一个名称是一个字符串;一个值 (value)可以是双引号括起来的字符串(string)、数值(number)、true、false、null、对象(object)或者数组(array)。这些结构可以嵌套

JSON语法规则:(1)、数据在键值对中;(2)、数据由逗号分隔;(3)、花括号保存对象;(4)、方括号保存数组。

JSON的值可以是:

(1)、数值:一系列0-9的数字组合,可以为负数或者小数。还可以用”e”或者”E”表示为指数形式。数值(number)也与C或者Java的数值非常相似。除去未曾使用的八进制与十六进制格式。除去一些编码细节。

(2)、字符串:以""括起来的一串字符。字符串(string)是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。字符串(string)与C或者Java的字符串非常相似。

(3)、布尔值:表示为true或者false。

(4)、数组(Array):数组是值(value)的有序集合。一个数组以”[“(左中括号)开始,”]”(右中括号)结束。值之间使用”,”(逗号)分隔。数组索引从0开始。

(5)、对象(object):对象是一个无序的”名称/值”对集合。一个对象以”{“开始,并以”}”结束。每个”名称”后跟一个”:”(冒号)。”名称/值”对之间使用”,”(逗号)分隔。

(6)、null

空白可以加入到任何符号之间。

各式各样开源的JSON库非常多,这里介绍下GitHub上dropbox的json11库的使用,地址:https://github.com/dropbox/json11,它用起来非常方便,只有两个文件,一个json11.hpp,一个json11.cpp。

新建一个Json11_Test控制台工程,将json11的两个文件加入到此工程中,测试代码Json11_Test.cpp如下:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include "json11.hpp"

#ifdef _MSC_VER
#include <Windows.h>
static std::string utf8_to_gbk(const char* utf8) {
	char gbk[256];
	const int maxlen = 256;
	wchar_t unicode_str[maxlen];
	int outlen = MultiByteToWideChar(CP_UTF8, 0, utf8, strlen(utf8), unicode_str, maxlen);
	outlen = WideCharToMultiByte(CP_ACP, 0, unicode_str, outlen, gbk, 256, NULL, NULL);
	gbk[outlen] = '\0';

	std::string str;
	str.assign(gbk);
	return str;
}
#endif

int test1();
int test2();
int test3();
int test4();

int main()
{
	test4();

	std::cout << "ok" << std::endl;
	return 0;
}

int test4()
{
	//std::istringstream  
	std::filebuf in;
	if (!in.open("E:/GitCode/Messy_Test/testdata/json.data", std::ios::in)) {
		std::cout << "fail to open file" << std::endl;
		return -1;
	}

	std::istream iss(&in);

	std::istreambuf_iterator<char> eos;
	std::string s(std::istreambuf_iterator<char>(iss), eos);
	std::string err;
	auto json = json11::Json::parse(s, err);
	if (!err.empty()) {
		in.close();
		return -1;
	}

	std::cout << "************** show file info *****************" << std::endl;
	std::string json_str = json.dump();
	std::cout << json_str << std::endl;

	std::cout << "*************** start parse ****************" << std::endl;

	std::string name = json["name"].string_value();
	std::string addr = json["address"].string_value();
	int age = json["age"].int_value();
	
	json11::Json::array array_ = json["value1"].array_items();
	std::vector<std::vector<float>> value1;
	value1.resize(array_.size());
	for (int i = 0; i < array_.size(); i++) {
		json11::Json::array tmp = array_[i].array_items();

		value1[i].resize(tmp.size());
		for (int j = 0; j < tmp.size(); j++) {
			value1[i][j] = tmp[j].number_value();
		}
	}
	
	std::vector<float> value2;
	array_ = json["value2"].array_items();
	value2.resize(array_.size());
	for (int i = 0; i < array_.size(); i++) {
		value2[i] = array_[i].number_value();
	}

	std::string beijing_addr;
	bool beijing_car, beijing_cat;
	if (json["bei_jing"].is_null()) {
		std::cout << "failed to get bei_jing info" << std::endl;
	} else {
		json11::Json::object object_ = json["bei_jing"].object_items();

		beijing_addr = object_["address"].string_value();
		beijing_car = object_["car"].bool_value();
		beijing_cat = object_["cat"].bool_value();
	}

	std::string shandong_addr, tmp_addr;
	std::vector<std::string> shandong_value1;
	if (json["shan_dong"].is_null()) {
		std::cout << "failed to get shan_dong info" << std::endl;
	} else {
		json11::Json::object object_ = json["shan_dong"].object_items();

		tmp_addr = object_["tmp"].string_value();
		if (tmp_addr == "") {
			std::cout << "tmp is null" << std::endl;
		}

		shandong_addr = object_["address"].string_value();

		json11::Json::array tmp = object_["value1"].array_items();
		shandong_value1.resize(array_.size());
		json11::Json json_ = tmp[0];
		shandong_value1[0] = json_["ji_nan"].string_value();
		json_ = tmp[1];
		shandong_value1[1] = json_["tai_an"].string_value();
	}

	std::cout << "************** parse result ***************" << std::endl;
	std::cout << "name: " << utf8_to_gbk(name.c_str()) << std::endl;
	std::cout << "address: " << utf8_to_gbk(addr.c_str()) << std::endl;
	std::cout << "age: " << age << std::endl;

	std::cout << "value1: " << std::endl;
	for (int i = 0; i < value1.size(); i++) {
		for (int j = 0; j < value1[i].size(); j++) {
			std::cout << "  " << value1[i][j];
		}
		std::cout << std::endl;
	}

	std::cout << "value2: " << std::endl;
	for (int i = 0; i < value2.size(); i++) {
		std::cout << "  " << value2[i];
	}
	std::cout << std::endl;

	std::cout << "bei_jing info: " << std::endl;
	std::cout << "  address: " << utf8_to_gbk(beijing_addr.c_str()) << std::endl;
	std::cout << "  car: " << beijing_car << std::endl;
	std::cout << "  cat: " << beijing_cat << std::endl;

	std::cout << "shan_dong info: " << std::endl;
	std::cout << "  address: " << utf8_to_gbk(shandong_addr.c_str()) << std::endl;
	std::cout << "  value1: " << std::endl;
	std::cout << "    ji_nan: " << utf8_to_gbk(shandong_value1[0].c_str()) << std::endl;
	std::cout << "    tai_an: " << utf8_to_gbk(shandong_value1[1].c_str()) << std::endl;

	in.close();
	return 0;
}

int test1()
{
	json11::Json my_json = json11::Json::object{
			{ "中国", "北京" },
			{ "key2", false },
			{ "key3", json11::Json::array { 1, 2, 3 } },
	};
	std::string json_str = my_json.dump();
	std::string key_1 = my_json["中国"].string_value();

	std::cout << json_str << std::endl;
	std::cout << key_1 << std::endl;

	return 0;
}

int test2()
{
	class Point {
	public:
		int x;
		int y;
		Point(int x, int y) : x(x), y(y) {}
		json11::Json to_json() const { return json11::Json::array { x, y }; }
	};

	std::vector<Point> points = { { 1, 2 }, { 10, 20 }, { 100, 200 } };
	std::string points_json = json11::Json(points).dump();

	std::cout << points_json << std::endl;

	return 0;
}

int test3()
{
	json11::Json json = json11::Json::array { json11::Json::object{ { "k", "v" } } };
	std::string str = json[0]["k"].string_value();

	std::cout << str << std::endl;

	return 0;
}

自己写了个Json格式的文本文件json.data,内容如下:

{
  "name": "spring",
  "address": "北京",
  "age": 30,
  "value1": [[23, 43, -2.3, 6.7, 90],
             [-9, -19, 10, 2],
             [-5, -55]],
  "value2": [13.3, 1.9, 2.10],
  
  "bei_jing": {
    "address": "海淀",
    "car": false,
    "cat": true
  },
  "shan_dong": {
    "address": "济南",
    "value1": [{"ji_nan": "趵突泉"}, {"tai_an": "泰山"}]
  }
}

测试代码中的test4()会调用json.data文件,执行结果如下图所示:

 

主要参考文献:

1. https://zh.wikipedia.org/wiki/JSON

2. http://www.json.org/json-zh.html

GitHubhttps://github.com/fengbingchun/Messy_Test

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

json11库的使用 的相关文章

  • C++中static_cast/const_cast/dynamic_cast/reinterpret_cast的区别和使用

    C风格的强制转换较简单 如将float a转换为int b 则可以这样 b int a 或者b int a C 类型转换分为隐式类型转换和显示类型转换 隐式类型转换又称为标准转换 包括以下几种情况 1 算术转换 在混合类型的算术表达式中 最
  • C++中的虚函数表介绍

    在C 语言中 当我们使用基类的引用或指针调用一个虚成员函数时会执行动态绑定 因为我们直到运行时才能知道到底调用了哪个版本的虚函数 所以所有虚函数都必须有定义 通常情况下 如果我们不使用某个函数 则无须为该函数提供定义 但是我们必须为每一个虚
  • C++/C++11中头文件algorithm的使用

  • C++11中模板类std::enable_shared_from_this的使用

    C 11中的模板类template
  • C和C++安全编码笔记:动态内存管理

    4 1 C内存管理 C标准内存管理函数 1 malloc size t size 分配size个字节 并返回一个指向分配的内存的指针 分配的内存未被初始化为一个已知值 2 aligned alloc size t alignment siz
  • C++11中std::future的使用

    C 11中的std future是一个模板类 std future提供了一种用于访问异步操作结果的机制 std future所引用的共享状态不能与任何其它异步返回的对象共享 与std shared future相反 std future r
  • C和C++安全编码笔记:文件I/O

    C和C 程序通常会对文件进行读写 并将此作为它们正常操作的一部分 不计其数的漏洞正是由这些程序与文件系统 其操作由底层操作系统定义 交互方式的不规则性而产生的 这些漏洞最常由文件的识别问题 特权管理不善 以及竞争条件导致 8 1 文件I O
  • OpenCV代码提取:遍历指定目录下指定文件的实现

    OpenCV 3 1之前的版本 在contrib目录下有提供遍历文件的函数 用起来比较方便 但是在最新的OpenCV 3 1版本给去除掉了 为了以后使用方便 这里将OpenCV 2 4 9中相关的函数给提取了出来 适合在Windows 64
  • 提高C++性能的编程技术笔记:引用计数+测试代码

    引用计数 reference counting 基本思想是将销毁对象的职责从客户端代码转移到对象本身 对象跟踪记录自身当前被引用的数目 在引用计数达到零时自行销毁 换句话说 对象不再被使用时自行销毁 引用计数和执行速度之间的关系是与上下文紧
  • C++11中std::bind的使用

    std bind函数是用来绑定函数调用的某些参数的 std bind它可以预先把指定可调用实体的某些参数绑定到已有的变量 产生一个新的可调用实体 它绑定的参数的个数不受限制 绑定的具体哪些参数也不受限制 由用户指定 std bind 1 将
  • json11库的使用

    JSON JavaScript Object Notation 是一种轻量级的文本数据交换格式 易于让人阅读 同时也易于机器解析和生成 尽管JSON是Javascript的一个子集 但JSON是独立于语言的文本格式 并且采用了类似于C语言家
  • C++14中返回类型推导的使用

    使用C 14中的auto返回类型 编译器将尝试自动推导 deduce 返回类型 namespace int xx 1 auto f return xx return type is int const auto f3 return xx r
  • C++中的封装、继承、多态

    封装 encapsulation 就是将抽象得到的数据和行为 或功能 相结合 形成一个有机的整体 也就是将数据与操作数据的源代码进行有机的结合 形成 类 其中数据和函数都是类的成员 封装的目的是增强安全性和简化编程 使用者不必了解具体的实现
  • cJSON介绍及使用

    JSON JavaScript Object Notation 是一种轻量级的文本数据交换格式 易于让人阅读 同时也易于机器解析和生成 尽管JSON是Javascript的一个子集 但JSON是独立于语言的文本格式 并且采用了类似于C语言家
  • C++中typeid的使用

    RTTI Run TimeType Information 运行时类型信息 它提供了运行时确定对象类型的方法 在C 中 为了支持RTTI提供了两个操作符 dynamic cast和typeid The typeid operator pro
  • CSV文件简介及C++实现

    逗号分隔值 Comma Separated Values CSV 有时也称为字符分隔值 因为分隔字符也可以不是逗号 其文件以纯文本形式存储表格数据 数字和文本 纯文本意味着该文件是一个字符序列 不含必须象二进制数字那样被解读的数据 CSV文
  • C/C++中#pragma once的使用

    在C C 中 为了避免同一个文件被include多次 有两种方式 一种是 ifndef方式 一种是 pragma once方式 在头文件的最开始加入 ifndef SOME UNIQUE NAME HERE define SOME UNIQ
  • C++11中thread_local的使用

    C 11中的thread local是C 存储期的一种 属于线程存储期 存储期定义C 程序中变量 函数的范围 可见性 和生命周期 C 程序中可用的存储期包括auto register static extern mutable和thread
  • C++/C++11中头文件iterator的使用

  • 开源库jemalloc简介

    jemalloc是通用的malloc 3 实现 它强调避免碎片和可扩展的并发支持 它的源码位于https github com jemalloc jemalloc 最新稳定版本为5 2 1 glibc的内存分配算法是基于dlmalloc实现

随机推荐

  • Locust压力测试使用总结

    上次做接口压力测试前一直研究使用jmeter 本以为可以拿来使用了 但是真正进行并发接口时 发现jmeter在单机下并发1000个时 台式电脑单机资源早就被使用完 整个jmeter卡得死死的 结果那晚使用jmeter并发失败 幸好之前也准备
  • FFmpeg学习笔记--视频传输的基本概念

    目录 1 容器 container 和文件 file 2 媒体流 stream 3 数据帧 frame 和数据包 packet 4 编解码器 Codec 5 复用 mux 6 解复用 demux 7 码率 bps 和帧率 fps 8 ffm
  • 【Android -- 写作工具】Markdown 代码块

    1 前言 关于代码块 Markdown 作者给出的定义如下 预格式化代码块主要用于在 Markdown 文档中显示源代码风格的内容 相比普通的文本段落 代码块可以保留文字内容的多行换行 缩进等格式 在 Markdown 文档中生成代码块 需
  • Numpy中的(一维)数组和(行列)向量

    Numpy中的 一维 数组和 行列 向量 随笔记录 Numpy的数组和行列向量的区别 随笔记录 Numpy的数组和行列向量的区别 今天做sklearn的datasets diabetes 的实验 做了个操作 diabetes是一个442 1
  • 【FPGA的基础快速入门17------频率计】

    FPGA的基础学习 频率计 频率计简介 等精度频率计 频率计简介 频率计又称为频率计数器 是一种专门对被测信号频率进行测量的电子测量仪器 计数法 直接计数单位时间内被测信号的脉冲数 这种方法测量精度高 速度快 适合不同频率 不同精确度测频的
  • 输入一个四位整数,分别输出组成该四位数的各位数字

    一 代码实现 1 include
  • Spring框架支持哪几种Bean作用域?自动装配Bean有哪些方式?

    Spring框架支持哪几种Bean作用域 spring支持五种Bean作用域 singleton 单例 就是每个spring容器只有一个 实例对象 prototype 多例 一个bean可以定义多个实例 另外三个是在web的Spring A
  • dell服务器启动顺序如何设置_戴尔品牌机怎么设置启动顺序(按F12进bios的)?

    展开全部 这主板非常麻烦 可关了保护 并切换 Legacy启动模式 U盘PE 装完系统 要改回uefi模式 DELL bios操作一32313133353236313431303231363533e59b9ee7ad943133343137
  • 传输线的物理基础(二):信号在传输线中的速度

    铜中电子的速度 信号在传输线上传输的速度有多快 如果人们经常错误地认为信号在传输线上的速度取决于导线中电子的速度 凭着这种错误的直觉 我们可能会想象降低互连的电阻会提高信号的速度 事实上 典型铜线中电子的速度实际上比信号速度慢约 100 亿
  • NLP中的数据增强方法!

    作者简介 大家好我是 uu 人工智能硕博在读 精通python 某大厂nlp算法经历 机器学习 深度学习 自然语言处理 计算机视觉 个人主页 uu主页 觉得uu写的不错的话 麻烦动动小手 点赞 收藏 评论 今天给大家带来的刷题系列是 NLP
  • BUS creator & selector、Mux&Demux

    2 3 总线BUS creator selector Bus Creator 由几路输入信号合成为一条总线信号 Bus Selector 由总线信号中选取需要的一路或几路信号输出 Mux 信号合成 Demux 信号分解 区别 Bus的可选择
  • vue web在线聊天功能实现

    上一篇介绍了vue怎么实现无限滚动窗体 这一篇就具体怎么使用vue实现web在线聊天功能展开深入讨论 对尚且不清楚怎么实现无限滚动窗体的 可前往这里查看 vue和iview实现无限滚动的正确解法 先看看最终实现的效果 实现过程 无限滚动窗体
  • 【ChatGPT进阶】如何使用ChatGPT做知乎好物?

    如果你想通过知乎赚钱 知乎好物是一个不错的选择 门槛很低 而且是一个可以长期 躺赚 的项目 如果你会ChatGPT的话 可以去卷同行 知乎好物是什么 知乎好物是一种在知乎平台上创作内容或回答问题时 使用 好物推荐 功能在内容中插入商品卡片
  • AI绘画StableDiffusion美女实操教程:斗破苍穹-小医仙-天毒女(附高清图下载)

    小医仙 是天蚕土豆所著玄幻小说 斗破苍穹 1 及其衍生作品中的角色 身负厄难毒体 食毒修炼 万毒不侵 通体毒气 这种会无意识地杀死别人的体质让天性善良的小医仙成为人憎鬼厌的天毒女 在萧炎多次帮助下得以控制 出图效果展示 资源整合 今天我们就
  • springboot集成RabbitMQ-超级详细步骤

    本文对应的代码地址 https github com zhangshilin9527 rabbitmq study 前置工作 1 安装rabbitmq 2 登录 地址 http localhost 15672 账号密码 guest gues
  • mybatis学习(31):修改部分字段(有外键,先查询,再修改)

    目录结构 com geyao mybatis mapper BlogMapper类 package com geyao mybatis mapper import java util List import java util Map im
  • vue利用路由控制实现登录功能

    未使用服务器接口 登录信息保存在cookie中 可以实现登录功能 vue交流群203849104 vue使用cookie首先需要安装cookie npm install js cookie 然后在router下面的index js文件中引入
  • 线程池ThreadPoolExecutor源码解析

    参考视频 首先回顾一下创建线程等的三种方式 第一个是直接继承Thread类 重写run方法 这个其实内部也是继承了Runnable接口重写run方法 比如 public class MyThread extends Thread Overr
  • oracle查看数据文件大小,路径及修改大小

    查看数据文件占用大小使用大小 select b file id 文件ID号 b tablespace name 表空间名 b bytes 1024 1024 M 字节数 b bytes sum nvl a bytes 0 1024 1024
  • json11库的使用

    JSON JavaScript Object Notation 是一种轻量级的文本数据交换格式 易于让人阅读 同时也易于机器解析和生成 尽管JSON是Javascript的一个子集 但JSON是独立于语言的文本格式 并且采用了类似于C语言家