C/C++ 中 JSON 库的使用 (CJSON/nlohmann)

news/2024/4/25 16:03:53/文章来源:https://blog.csdn.net/qq_21438461/article/details/129202336

C/C++ 中 JSON 库的使用 (CJSON/nlohmann)

  • 概述
  • cjson
    • 基本操作
      • 从(字符指针)缓冲区中解析出JSON结构
      • 转成成JS字符串(将传入的JSON结构转化为字符串)
      • 将JSON结构所占用的数据空间释放
    • JSON 值的创建
      • 创建一个值类型的数据
      • 创建一个对象(文档)
      • 数组创建以及添加
    • JSON嵌套
      • 向对象中增加键值对
      • 向数组中增加对象
      • 几个能提高操作效率的宏函数
    • 查找JSON值
      • 根据键找json结点
      • 判断是否有key是string的项
      • 返回数组结点array中成员的个数
      • 根据数组下标index取array数组结点的第index个成员
      • 遍历数组
  • nlohmann
    • nlohmann库使用代码示例


概述

纯C环境中使用cjson库,C++环境中也可以使用nlohmann库,本文介绍基本的使用场景,如需更详细的介绍可以查看库官方文档。


nlohmann:

nlohmann库(https://github.com/nlohmann/json)提供了丰富而且符合直觉的接口(https://json.nlohmann.me/api/basic_json/),只需导入头文件即可使用,方便整合到项目中。

CJSON:

JSON: JavaScript Object Notation(JavaScript 对象表示法),是轻量级的存储和交换文本信息的语法,类似 XML . 特点是纯文本(纯字符串)、层级结构、使用数组。
cJson:一个基于 C 语言的 Json 库,它是一个开源项目,github 下载地址:https://github.com/DaveGamble/cJSON
cJson库组成:主要的文件有两个,一个 cJSON.c 一个 cJSON.h。使用时,将头文件 include 进去即可

cjson

typedef struct cJSON {  //cJSON结构体struct cJSON*next,*prev;           /* 遍历数组或对象链的前向或后向链表指针*/struct cJSON *child;                   /*数组或对象的孩子节点*/int type;                                     /* key的类型*/char *valuestring;                       /*字符串值*/int valueint;                                /* 整数值*/double valuedouble;                    /* 浮点数值*/char *string;                               /* key的名字*/
} cJSON_st;
extern cJSON *cJSON_Parse(const char *value);       
//解析一块JSON数据返回cJSON结构, 在使用完之后调用cJSON_Delete函数释放json对象结构。

解析JSON数据包,并按照cJSON结构体的结构序列化整个数据包。

使用该函数会通过malloc函数在内存中开辟一个空间,使用完成需要手动释放。

  • 转成成JS字符串(将传入的JSON结构转化为字符串)

extern char *cJSON_Print(cJSON *item); //可用于输出到输出设备,
使用完之后free(char *)  cJSON_PrintUnformatted(cJSON *item);
//类似,没有格式,即转换出的字符串中间不会有"\n" "\t"之类的东西存在. 
  • 将JSON结构所占用的数据空间释放

void cJSON_Delete(cJSON *c)
//会将其下的所有节点的资源一并释放掉!!    
extern cJSON *cJSON_CreateNumber(double num);//创建 extern cJSON
*cJSON_CreateString(const char *string); 
//创建 extern cJSON *cJSON_CreateArray(void); //创建json数组
  • 创建一个对象(文档)

extern cJSON *cJSON_CreateObject(void);
//创建一个根数据项,之后便可向该根数据项中添加string或int等内容 
  • 数组创建以及添加

cJSON *cJSON_CreateIntArray(const int *numbers,int count);void cJSON_AddItemToArray(cJSON *array, cJSON *item); 
 cJSON_AddItemToObject(root, "rows", 值类型数据相关函数());
  • 向对象中增加数组
cJSON_AddItemToObject(root, "rows", cJSON_CreateArray());
//创建一个根数据项,之后便可向该根数据项中添加string或int等内容 
  • 向数组中增加对象

cJSON_AddItemToArray(rows, cJSON_CreateObject());
//向json数组中增加元素/对象
  • 几个能提高操作效率的宏函数

#define cJSON_AddNumberToObject(object,name,n)   cJSON_AddItemToObject(object, name,cJSON_CreateNumber(n))
//向json对象中添加数字,节点名and节点值#define cJSON_AddStringToObject(object,name,s)   cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) 
// 向json对象中添加字符串
extern cJSON *cJSON_GetObjectItem(cJSON *object,const char*string) 
//从cJSON结构体中查找某个子节点名称(键名称),如果查找成功可把该子节点序列化到cJSON结构体中。 
  • 判断是否有key是string的项

extern int cJSON_HasObjectItem(cJSON *object,const char *string){
return cJSON_GetObjectItem(object,string)?1:0; } 
//如果有返回1 否则返回0 
  • 返回数组结点array中成员的个数


extern int cJSON_GetArraySize(cJSON *array); 
  • 根据数组下标index取array数组结点的第index个成员

 
extern cJSON *cJSON_GetArrayItem(cJSON *array,int index);
//返回该成员节点  
  • 遍历数组

#define cJSON_ArrayForEach(pos, head) for(pos = (head)->child; pos != NULL; pos = pos->next)  cJSON_ReplaceItemInObject(json,"data",cJSON_CreateString("hello"))
//用于代替json对象中data元组的值 

nlohmann

使用方式比较简单,下面直接通过示例来说明.


nlohmann库使用代码示例

#pragma once#include <iostream>
#include <fstream>
#include <string>
#include <nlohmann/json.hpp>static bool JsonConfigInit(const std::string& config_file)bool ret = false;std::ifstream cfg_file(config_file);if (!cfg_file.is_open()) {nlohmann::json configjson;                  //创建一个空结构configjson["config_settings"] = { {"bool_value", true},{"file_size", 15},{"info_file", "./tmp.ini"}};//对对象进行初始化std::ofstream(config_file.c_str()) << configjson;std::cout  << "create config json file"<< std::endl;return false;}try{std::cout   <<  "JsonConfigInit  from \" " << config_file<< "\" "<< std::endl;const nlohmann::json&  file_json = nlohmann::json::parse(cfg_file);//判断首节点是否存在if(file_json.is_null() || (file_json.contains("config_settings") == false ) || file_json.at("config_settings").size() == 0){ret = false; goto json_end;}nlohmann::json  set_json = file_json.at("config_settings");      //	获取相应的键值对,get_to必须保证双方类型一致,否则极易出现段错误bool m_json_bool;int m_json_number;std::string m_json_string ;if(set_json.at("bool_value").is_boolean()){set_json.at("bool_value").get_to(m_json_bool);}if(set_json.at("file_size").is_number()){set_json.at("file_size").get_to(m_json_number);}if(set_json.at("info_file").is_string()){set_json.at("info_file").get_to(m_json_string);}ret = true;}}catch (nlohmann::json::parse_error& ex){  std::cerr   << "JsonConfigInit failed:parse error ! ! reason: [" << ex.what() << "]"<< std::endl;}catch (nlohmann::json::exception& ex){std::cerr   << "JsonConfigInit parse_json parse fail! reason: [" << ex.what() << "]"<< std::endl;}json_end: cfg_file.close();return ret;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_73691.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

「RISC-V Arch」SBI 规范解读(上)

术语 SBI&#xff0c;Supervisor Binary Interface&#xff0c;管理二进制接口 U-Mode&#xff0c;User mode&#xff0c;用户模式 S-Mode&#xff0c;Supervisor mode&#xff0c;监督模式 VS-Mode&#xff0c;Virtualization Supervisor mode&#xff0c;虚拟机监督模式 …

电商共享购模式,消费增值返利,app开发

在当今以市场需求为主导的数字经济时代&#xff0c;消费者需求呈现出精细化管理和多元化的特性&#xff0c;目标市场日渐完善&#xff0c;另外在大数据技术迅速进步和运用的驱动下&#xff0c;总体行业的发展节奏感也在不断加速。因而&#xff0c;企业需要建立一套灵活多变的经…

HyperGBM用Adversarial Validation解决数据漂移问题

本文作者&#xff1a;杨健&#xff0c;九章云极 DataCanvas 主任架构师 数据漂移问题近年在机器学习领域来越来越得到关注&#xff0c;成为机器学习模型在实际投产中面对的一个主要挑战。当数据的分布随着时间推移逐渐发生变化&#xff0c;需要预测的数据和用于训练的数据分布…

格雷码的实现

格雷码&#xff1a;任意两个相邻的二进制数之间只有一位不同 想必通信专业的学生应该都接触过格雷码&#xff0c;它出现在数电、通信原理等课程里。 如下图所示一个四位格雷码是什么样子的&#xff1a; 格雷码的特点&#xff1a; 其最大的特点是任意上下相邻的两个码值间&am…

线性数据结构:数组 Array

一、前言数组是数据结构还是数据类型&#xff1f;数组只是个名称&#xff0c;它可以描述一组操作&#xff0c;也可以命名这组操作。数组的数据操作&#xff0c;是通过 idx->val 的方式来处理。它不是具体要求内存上要存储着连续的数据才叫数组&#xff0c;而是说&#xff0c…

内网渗透(五十六)之域控安全和跨域攻击-非约束委派攻击

系列文章第一章节之基础知识篇 内网渗透(一)之基础知识-内网渗透介绍和概述 内网渗透(二)之基础知识-工作组介绍 内网渗透(三)之基础知识-域环境的介绍和优点 内网渗透(四)之基础知识-搭建域环境 内网渗透(五)之基础知识-Active Directory活动目录介绍和使用 内网渗透(六)之基…

Linux下java服务占用cpu过高如何处理

Linux下java服务占用cpu过高如何处理 top命令查看进程信息 top按下shiftp,按cpu使用率排行,可见进程1932占用最高,并且是一个java服务 使用jps命令确认java服务 [rootVM-16-16-centos ~]# jps 1011 Jps 9462 yuan_back-0.0.1-SNAPSHOT.jar 1932 spigot-1.18.jar查找异常进程中…

利用关联来发现复杂攻击模式

日志是网络活动的重要依据&#xff0c;包含了关于您网络上所有用户和系统活动的详尽信息。基本日志分析可帮助您轻松地对数百万个日志进行分类&#xff0c;并挑选出可以表明存在可疑活动的日志&#xff0c;识别与正常网络活动不符的异常日志。通常&#xff0c;单独查看某个日志…

GCC:从源文件到可执行文件

GCC&#xff1a;从源文件到可执行文件 假设我们有hello.c 文件 #include <stdio.h> int main(){printf("hello world!\n");return 0; }怎么在linux上利用GCC命令生产可执行文件&#xff08;单文件编译&#xff09;呢&#xff1f; 一、流程 C文件从源文件到…

5.35 综合案例2.0 -称重数据上传云端

综合案例2.0 - 称重数据上传云端案例说明连线功能实现1.阿里云平台连接代码应用开发3.1新建‘普通项目’3.2关联产品和设备3.3新建‘移动应用’3.4添加组件3.5配置组件信息3.6保存预览案例说明 使用hx711串口模块称重,结合IOT studio制作手机APP远程控制并采集物体重量。 hx7…

称重传感器差分输入信号隔离转换直流放大变送器0-±10mV/0-±20mV转0-10V/4-20mA

主要特性DIN11 IPO 压力应变桥信号处理系列隔离放大器是一种将差分输入信号隔离放大、转换成按比例输出的直流信号导轨安装变送模块。产品广泛应用在电力、远程监控、仪器仪表、医疗设备、工业自控等行业。此系列模块内部嵌入了一个高效微功率的电源&#xff0c;向输入端和输出…

Oracle——物化视图

文章目录含义物化视图的语法物化视图的创建1、自动刷新的物化事务 ON COMMIT2、非自动刷新的物化视图 ON demand关于手动刷新物化视图的删除资料参考含义 什么是物化视图&#xff1f; 物化视图&#xff0c;通俗点说就是物理化的视图。 什么叫物理化&#xff1f; 将视图以表结构…

可怕,chatGPT用3小时教会我数据分析

chatGPT这玩意真的是我的救星,用它作为我的Python教练,我用三个小时学会了数据处理(Pandas)和绘图(matplotlib)。 这两个库的学习,在之前已经困扰了我7个月。之前卡壳的原因,是我一直没有耐心从零开始,按照教材设置的教程去学习Python——我擅长在项目中学习,一点一点…

SpringMVC框架知识详解(入门版)

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

「RISC-V Arch」SBI 规范解读(下)

第六章 定时器扩展&#xff08;EID #0x54494D45"TIME"&#xff09; 这个定时器扩展取代了遗留定时器扩展&#xff08;EID #0x00&#xff09;&#xff0c;并遵循 v0.2 中定义的调用规约。 6.1 函数&#xff1a;设置定时器&#xff08;FID #0&#xff09; struct sbi…

TensorFlow-Keras - FM、WideAndDeep、DeepFM、DeepFwFM、DeepFmFM 理论与实战

目录 一.引言 二.浅层模型概述 1.LR 2.FM 3.FMM 4.FwFM 5.FmFM 三.常用推荐算法实现 Pre.数据准备 1.FM 2.WideAndDeep 3.DeepFM 4.DeepFwFM 5.DeepFmFM 四.总结 1.函数测试 2.函数效果与复杂度对比[来自FmFM论文] 3.More 一.引言 推荐系统中常见的 CTR 模型…

梯度下降优化器:SGD -> SGDM -> NAG ->AdaGrad -> AdaDelta -> Adam -> Nadam -> AdamW

目录 1 前言 2 梯度概念 3 一般梯度下降法 4 BGD 5 SGD 6 MBGD 7 Momentum 8 SGDM&#xff08;SGD with momentum&#xff09; 9 NAG(Nesterov Accelerated Gradient) 10 AdaGrad 11 RMSProp 12 Adadelta 13 Adam 13 Nadam 14 AdamW 15 Lion&#xff08;EvoLve…

【C++进阶】一些小知识点

const限定符 用const给字面常量起个名字&#xff08;标识符&#xff09;&#xff0c;这个标识符就称为标识符常量&#xff1b;因为标识符常量的声明和使用形式很像变量&#xff0c;所以也称常变量。声明方式&#xff1a; const int a 77; const float PI 3.14159f&#xff…

算法设计与分析期末考试复习(二)

分治法 将一个难以直接解决的大问题&#xff0c;分割成一些规模较小的相同问题&#xff0c;以便各个击破&#xff0c;分而治之。最好使子问题的规模大致相同。 分解&#xff08;Divide&#xff09;&#xff1a;将一个难以直接解决的大问题&#xff0c;分割成一些规模较小的子…

【拿好了!Linux 运维必备的 13 款实用工具!】

​本文介绍几款 Linux 运维比较实用的工具&#xff0c;希望对 Linux 运维人员有所帮助。 查看进程占用带宽情况 – Nethogs Nethogs 是一个终端下的网络流量监控工具可以直观的显示每个进程占用的带宽。 下载&#xff1a; http://sourceforge.net/projects/nethogs/files/ne…