4.8 C++ Boost 应用JSON解析库

c++,boost,应用,json,解析 · 浏览次数 : 21

小编点评

* **初始化**函数: * **`InitArray`**:初始化列表,包括字符串、整数、向量。 * **`InitDict`**:初始化字典,包括字符串、整数、向量。 * **`InitJSON`**:初始化JSON文件,包括字符串、整数、向量。 * **`JsonIntToVector`**函数: * 将字符串转为整数容器。 * **``JsonStringToVector`**函数: * 将字符串转为字符串容器。 * **``std::system()`**函数: * 使用 `std::system``库将命令输出到 `std::cout`。 * **``std::vector`**类型: * 用于存储字符串、整数、向量等类型数据。 * **``boost::property_tree`**库: * 用于存储 JSON数据。 * 包含 ``property_tree``、``property_tree/json_parser``、``property_tree/json_writer``等类。 * **``std::string`**类型: * 用于存储字符串数据。 * **``boost::algorithm`**库: * 包含 ``string``、```string_cast``等类。 * **``boost::lexical_cast`**类: * 用于对字符串进行类型转换。 * **``boost::property_tree::ptree`**类: * 用于存储 JSON数据。 * **``boost::property_tree/json_parser`**类: * 用于解析 JSON字符串。 * **``boost::property_tree/json_writer`**类: * 用于解析 JSON字符串。

正文

property_tree 是 Boost 库中的一个头文件库,用于处理和解析基于 XML、Json 或者 INFO 格式的数据。 property_tree 可以提供一个轻量级的、灵活的、基于二叉数的通用容器,可以处理包括简单值(如 int、float)和复杂数据结构(如结构体和嵌套容器)在内的各种数据类型。它可以解析数据文件到内存中,然后通过迭代器访问它们。

在 Boost 库中,property_tree 通常与 boost/property_tree/xml_parser.hpp、boost/property_tree/json_parser.hpp 或 boost/property_tree/info_parser.hpp 文件一起使用。这些文件分别提供了将 XML、JSON 或 INFO 格式数据解析为 property_tree 结构的功能。

首先我们需要自行创建一个测试config.json文件,后期的所有案例演示及应用都需要这个库的支持。

{
    "username": "lyshark",
    "age": 24,
  "get_dict": { "username": "lyshark" },
    "get_list": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ],
    "user_data":
     [
        [ "192.168.1.1", "root", "123456" ],
        [ "192.168.1.2", "admin", "123456" ],
        [ "192.168.1.3", "mysql", "123456" ]
    ],

    "user_dict":
     [
        { "uid": 1001, "uname": "admin" },
        { "uid": 1002, "uname": "lyshark" },
        { "uid": 1003, "uname": "root" }
    ],

    "get_root":
     [
        {
            "firstName": "admin",
            "lastName": "JackWang",
            "email": "admin@lyshark.com"
        },
        {
            "firstName": "lyshark",
            "lastName": "xusong",
            "email": "me@lyshark.com"
        }
    ],
  
  "get_my_list":
  {
        "get_uint": "[1,2,3,4,5,6,7,8,9,0]", 
        "get_string": "['admin','lyshark','root']"
    }
}

8.1 解析单个节点

代码中使用了 Boost C++ 库中的 property_tree 和 json_parser 来解析 JSON 文件。它的主要功能是读取指定路径下的 "c://config.json" 文件,然后获取其中的用户名和年龄信息(如果存在的话),并将它们输出到控制台。

#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

using namespace std;

int main(int argc, char* argv[])
{
  boost::property_tree::ptree ptr;
  boost::property_tree::read_json("c://config.json", ptr);

  cout << "是否存在: " << ptr.count("username") << endl;
  if (ptr.count("username") != 0)
  {
    std::string username = ptr.get<std::string>("username");
    std::cout << "用户名: " << username << std::endl;
  }

  if (ptr.count("age") != 0)
  {
    int age = ptr.get<int>("age");
    std::cout << "年龄: " << age << std::endl;
  }

  system("pause");
  return 0;
}

8.2 解析单个列表

代码中使用了 Boost C++ 库中的 property_tree 和 json_parser 来解析 JSON 文件。它的功能是读取指定路径下的 "c://config.json" 文件,并提取名为 "get_list" 的字段的值,并将其输出到控制台。

#include <iostream>
#include <vector>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

using namespace std;

void GetJson(std::string &filePath)
{
  boost::property_tree::ptree ptr;
  std::vector<std::string> item;

  boost::property_tree::read_json(filePath, ptr);

  // 先判断是否存在字段
  if (ptr.count("get_list") == 1)
  {
    boost::property_tree::ptree pChild = ptr.get_child("get_list");
    for (auto pos = pChild.begin(); pos != pChild.end(); ++pos)
    {
      // 迭代循环,将元素房补vector列表中
      std::string list = pos->second.get_value<string>();
      item.push_back(list);
    }
  }

  // 迭代输出vector中的数据
  for (auto x = item.begin(); x != item.end(); ++x)
  {
    cout << *x << endl;
  }
}

int main(int argc, char* argv[])
{
  GetJson(std::string("c://config.json"));
  system("pause");
  return 0;
}

8.3 解析嵌套列表

这段代码依然使用了 Boost C++ 库中的 property_tree 和 json_parser 来解析 JSON 文件。它的功能是读取指定路径下的 "c://config.json" 文件,并提取名为 "user_data" 的字段的第二列数据,并将其输出到控制台。

#include <iostream>
#include <vector>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

using namespace std;

void GetJson(std::string &filePath)
{
  boost::property_tree::ptree ptr;
  boost::property_tree::read_json(filePath, ptr);

  std::vector<std::string> item;

  for (auto& root_child : ptr.get_child("user_data"))
  {
    int count = 1;
    for (auto& x : root_child.second)
    {
      // count 用于指定需要那一列的记录
      if (count == 2)
      {
        std::string sub_data = x.second.get_value<std::string>();
        cout << "输出元素: " << sub_data << endl;
        item.push_back(sub_data);
      }
      count++;
    }
  }

  // 迭代输出vector中的数据
  for (auto x = item.begin(); x != item.end(); ++x)
  {
    cout << *x << endl;
  }
}

int main(int argc, char* argv[])
{
  GetJson(std::string("c://config.json"));
  system("pause");
  return 0;
}

8.4 解析多层字典

代码同样使用了 Boost C++ 库中的 property_tree 和 json_parser 来解析 JSON 文件。它的功能是读取指定路径下的 "c://config.json" 文件,并提取名为 "get_dict" 和 "user_dict" 的字段数据,并将其输出到控制台。

#include <iostream>
#include <vector>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

using namespace std;

void GetJson(std::string &filePath)
{
  boost::property_tree::ptree ptr;
  boost::property_tree::read_json(filePath, ptr);

  // 解析单一字典
  std::string username = ptr.get_child("get_dict").get<std::string>("username");
  cout << "姓名: " << username << endl;

  // 解析多层字典
  boost::property_tree::ptree root_ptr, item;
  root_ptr = ptr.get_child("user_dict");

  // 输出第二层
  for (boost::property_tree::ptree::iterator it = root_ptr.begin(); it != root_ptr.end(); ++it)
  {
    item = it->second;
    cout << "UID: " << item.get<int>("uid") << " 姓名: " << item.get<string>("uname") << endl;
  }
}

int main(int argc, char* argv[])
{
  GetJson(std::string("c://config.json"));
  system("pause");
  return 0;
}

第二种方式,通过多次迭代解析多层字典,并将字典中的特定value放入到vector容器内。

#include <iostream>
#include <string>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

using namespace std;
using namespace boost;
using namespace boost::property_tree;

int main(int argc, char *argv[])
{
  boost::property_tree::ptree ptr;
  boost::property_tree::read_json("C://config.json", ptr);

  // 判断是否存在get_root
  if (ptr.count("get_root") == 1)
  {
    std::vector<string> vecStr;
    std::string get_first_name;
    
    boost::property_tree::ptree p1, p2;

    // 读取到根节点
    p1 = ptr.get_child("get_root");

    // 循环枚举
    for (ptree::iterator it = p1.begin(); it != p1.end(); ++it)
    {
      // 获取到字典的value值
      p2 = it->second;
      get_first_name = p2.get<string>("firstName");

      // 将获取到的value转换为vector容器
      vecStr.push_back(get_first_name);
    }

    // 输出容器中的内容
    for (int x = 0; x < vecStr.size(); x++)
    {
      std::cout << vecStr[x] << std::endl;
    }
  }
  std::system("pause");
  return 0;
}

8.5 写出JSON文件

#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

using namespace std;

// 初始化字符串
bool InitJSON()
{
  string str = "{\"uuid\":1001,\"Student\":[{\"Name\":\"admin\"},{\"Name\":\"lyshark\"}]}";
  stringstream stream(str);
  boost::property_tree::ptree strTree;

  try{
    read_json(stream, strTree);
  }
  catch (boost::property_tree::ptree_error & e) {
    return false;
  }
  write_json("c://config.json", strTree);
  return true;
}

// 初始化列表
void InitArray()
{
  boost::property_tree::ptree ptr;
  boost::property_tree::ptree children;
  boost::property_tree::ptree child1, child2, child3;

  child1.put("", 1);
  child2.put("", 2);
  child3.put("", 3);

  children.push_back(std::make_pair("", child1));
  children.push_back(std::make_pair("", child2));
  children.push_back(std::make_pair("", child3));

  ptr.add_child("MyArray", children);
  write_json("c://Array.json", ptr);
}

// 初始化字典
void InitDict()
{
  boost::property_tree::ptree ptr;
  boost::property_tree::ptree children;
  boost::property_tree::ptree child1, child2, child3;

  child1.put("childkeyA", 1);
  child1.put("childkeyB", 2);

  child2.put("childkeyA", 3);
  child2.put("childkeyB", 4);

  child3.put("childkeyA", 5);
  child3.put("childkeyB", 6);

  children.push_back(std::make_pair("", child1));
  children.push_back(std::make_pair("", child2));
  children.push_back(std::make_pair("", child3));

  ptr.put("testkey", "testvalue");
  ptr.add_child("MyArray", children);

  write_json("c://MyDict.json", ptr);
}

int main(int argc, char* argv[])
{
  InitArray();
  InitDict();
  InitJSON();

  boost::property_tree::ptree ptr;
  boost::property_tree::read_json("c://config.json", ptr);

  // 修改uuid字段
  if (ptr.count("uuid") != 0)
  {
    ptr.put("uuid", 10002);
  }
  boost::property_tree::write_json("c://config.json", ptr);

  system("pause");
  return 0;
}

8.6 自定义结构解析

#include <iostream>
#include <string>
#include <vector>
#include <boost/assign.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

using namespace std;
using namespace boost;
using namespace boost::property_tree;

// 将整数转为int容器
std::vector<int> JsonIntToVector(std::string string_ptr)
{
  std::vector<std::string> vect;

  // 去掉里面的[]符号
  std::string item = boost::trim_copy_if(string_ptr, (boost::is_any_of("[") || boost::is_any_of("]")));
  boost::split(vect, item, boost::is_any_of(",,"), boost::token_compress_on);

  std::vector<int> ref;
  for (auto each : vect)
  {
    ref.push_back(boost::lexical_cast<int>(each));
  }
  return ref;
}

// 将字符串列表转为string容器
std::vector<std::string> JsonStringToVector(std::string string_ptr)
{
  std::vector<std::string> ref;
  std::vector<std::string> vect;

  std::string item = boost::trim_copy_if(string_ptr, (boost::is_any_of("[") || boost::is_any_of("]")));
  boost::split(vect, item, boost::is_any_of(",,"), boost::token_compress_on);

  for (auto each : vect)
  {
    // 去掉单引号
    std::string ea = boost::trim_copy_if(each, (boost::is_any_of("'") || boost::is_any_of("\"")));
    ref.push_back(ea);
  }
  return ref;
}

int main(int argc, char *argv[])
{
  boost::property_tree::ptree ptr;
  boost::property_tree::read_json("./config.json", ptr);

  // 输出特殊的整数
  std::string ustring = ptr.get_child("get_my_list").get<std::string>("get_uint");
  std::vector<int> ref_int = JsonIntToVector(ustring);
  for (int x = 0; x < ref_int.size(); x++)
  {
    std::cout << "输出整数: " << ref_int[x] << std::endl;
  }
  
  // 输出特殊的字符串
  std::string ustring1 = ptr.get_child("get_my_list").get<std::string>("get_string");
  std::vector<std::string> ref_string = JsonStringToVector(ustring1);
  for (int x = 0; x < ref_string.size(); x++)
  {
    std::cout << "输出字符串: " << ref_string[x] << std::endl;
  }

    std::system("pause");
    return 0;
}

本文作者: 王瑞
本文链接: https://www.lyshark.com/post/ea32fbc2.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

与4.8 C++ Boost 应用JSON解析库相似的内容:

4.8 C++ Boost 应用JSON解析库

property_tree 是 Boost 库中的一个头文件库,用于处理和解析基于 XML、Json 或者 INFO 格式的数据。 property_tree 可以提供一个轻量级的、灵活的、基于二叉数的通用容器,可以处理包括简单值(如 int、float)和复杂数据结构(如结构体和嵌套容器)在内的各种数据类型。它可以解析数据文件到内存中,然后通过迭代器访问它们。在 Boost 库中,propert

4.1 C/C++ 使用结构与指针

C/C++语言是一种通用的编程语言,具有高效、灵活和可移植等特点。C语言主要用于系统编程,如操作系统、编译器、数据库等;C语言是C语言的扩展,增加了面向对象编程的特性,适用于大型软件系统、图形用户界面、嵌入式系统等。C/C++语言具有很高的效率和控制能力,但也需要开发人员自行管理内存等底层资源,对于初学者来说可能会有一定的难度。

C#泛型

目录C#泛型概述什么是泛型?泛型有什么用?基本语法1.泛型方法 Method2.泛型类 class GenericClass{}3.泛型接口 public interface GenericInterface{}4.泛型委托 public delegate void Generic

汉诺塔问题(递归)

博客地址:https://www.cnblogs.com/zylyehuo/ # _*_coding:utf-8_*_ def hanoi(n, a, b, c): if n > 0: hanoi(n - 1, a, c, b) print("moving from %s to %s" % (a,

C#.NET与JAVA互通之DES加密V2024

C#.NET与JAVA互通之DES加密V2024 配置视频: 环境: .NET Framework 4.6 控制台程序 JAVA这边:JDK8 (1.8) 控制台程序 注意点: 1.由于密钥、明文、密文的输入输出参数,都是byte数组(byte[]),所以:字符串转byte数组(byte[])环节,

C++ 初始化列表(Initialization List)

请注意以下继承体系中各class的constructors写法: 1 class CPoint 2 { 3 public: 4 CPoint(float x=0.0) 5 :_x(x){} 6 7 float x() {return _x;} 8 void x(float xval){_x=xval

[转帖]echo 输出不换行-e \c

http://www.my889.com/i/1952 在shell中,echo输出会自动换行。有时候在循环中不希望echo输出换行。代码实现如下: 1 echo -e " \c" # -e 表示开启转义, \c表示不换行 脚本: 1 2 3 4 5 6 7 8 9 #!/bin/bash i=1

【转帖】Linux性能优化(十三)——CPU性能测试

一、CPU上下文切换测试场景 使用sysbench模拟多线程调度: sysbench --threads=10 --time=300 threads run 使用vmstat查看CPU上下文切换: cs列上下文切换次数超过150万次。 r列就绪队列长度最大达到8,超过系统CPU的个数4,存在大量的C

Bridge 桥接模式简介与 C# 示例【结构型2】【设计模式来了_7】

〇、简介 1、什么是桥接模式? 一句话解释: 通过一个类的抽象,与另一个类的抽象关联起来,当做桥。此后不管两个抽象类的实现有多少种,均可以通过这个桥来将两个对象联系起来。 桥接,顾名思义就是用桥来连接河两岸,将原本不关联的两部分联系起来,且不影响两岸的各自演化,演化出来的不同对象仍可以通过这个桥连接

使用 Spacesniffer 找回 48G 系统存储空间的总结

前言 Spacesniffer 是一个免费的文件扫描工具,通过使用树状图可视化布局,可以立即了解大文件夹的位置,帮助用户处理找到这些文件夹 当前系统C盘空间 清理后系统C盘空间 下载 Spacesniffer 下载地址:https://spacesniffer.en.softonic.com/dow