【C++开发脚手架】 —— Jsoncpp上手

🌈欢迎来到C++专栏~~Jsoncpp上手


  • (꒪ꇴ꒪(꒪ꇴ꒪ )🐣,我是Scort
  • 🌍博客主页:张小姐的猫~江湖背景
  • 快上车🚘,握好方向盘跟我有一起打天下嘞!
  • 🎉🎉欢迎持续关注!

Jsoncpp上手

一. Json简介

JSON(JavaScriptObjectNotation)是⼀种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。它基于JavaScript的⼀个自子集,但尽管它来源于JavaScript,JSON是独立于语言的,可以被多种编程语言读取。以下是关于JSON的⼀些关键点:

json 复制代码
{
	"name": "John Doe",
	"age": 30,
	"is_student": false,
	"skills": ["JavaScript", "Python", "C++"],
	"address": 
	{
		"street": "123 Main St",
		"city": "Anytown",
		"state": "CA"
	}
}

Json常用于序列化

  • 序列化:将数据对象,按照指定的格式组织成为一个二进制数据串
  • 反序列化:将一个二进制数据串,按照指定格式解析得到其中的数据对象

二. JsonCpp

JsonCpp是⼀个高性能的JSON库,用于处理JSON数据。它提供了完整的JSON标准支持,包括解析JSON字符串、生成JSON字符串、读写JSON对象和数组等功能

对应的头文件是:

cpp 复制代码
#include <jsoncpp/json/json.h>

编译时记得要链接库-ljsoncpp

1️⃣典型类:Value

Json::Value类是中间数据转储类 ,如果要针对多个数据进行序列化 ,就要先将各个数据存储到Value对象中,针对Value来进行序列化

如果要针对Json字符串进行反序列化,内部会进行解析,将结果都存储到Value对象里

常用接口有:[]运算符重载

cpp 复制代码
json::Value val;

val["姓名"] = "卢本伟";
val["年龄"] = "33";

append接口:添加数组元素

c 复制代码
val["成绩"].append(77.5);

数据获取呢?

cpp 复制代码
auto name = val["姓名"].asString();

数组元素获取:

cpp 复制代码
val["成绩"].size() //获取数组元素个数

auto sum = val["成绩"][0].asDouble();

那么怎么判断这个字段是什么类型呢?

cpp 复制代码
bool isNull() const;
bool isArray() const;
bool isObject() const;

获取序列化后的数据:

cpp 复制代码
String toStyledString() const;

上手体验一下:

cpp 复制代码
#include <jsoncpp/json/json.h>

int main()
{
    Json::Value val;
    val["name"] = "DeepSeek-chat";
    val["desc"] = "一款实用性强,功能强大的聊天模型";
    val["model"] = "deepseek-3.5";
    val["apikey"] = "sk-xxxx";
    val["baseurl"] = "https://api.deepseek.cn/v1";
    std::string str = val.toStyledString();
    std::cout << str << std::endl;
    return 0;
}

2️⃣序列化

此处涉及了两个类

  • StreamWriter序列化类
  • StreamWriterBuilder类:StreamWriter建造者类
  • 构造接口newStreamWriter()

通过StreamWriterBuilder类来构建出序列化类StreamWriter来进行序列化

其中包含了write函数:------ 通常不会失败

cpp 复制代码
write(Value const& root, OStream* sout)

将一个jsonValue对象内部的数据按照指定格式,序列化之后输入到输出流里,我们从输出流中取出对应的数据

3️⃣反序列化

涉及了Char Reader类:反序列化类

也用到了一个parse函数:

cpp 复制代码
bool parse(char const* beginDoc, char const* endDoc, Value* root,String* errs) 
  • 给上字符串的起始和结束位置,根据其中的内容做反序列化解析,解析后的结果存储在root对象中
  • errs反序列化失败的原因

同理Char Reader类也无法直接构造,是由Char ReaderBuilder类:Char Reader建造者类来进行构造

  • Char Reader类:反序列化类
  • Char ReaderBuilder类:Char Reader建造者类
  • 构造接口newCharReader

✋️动手实践

操作流程:

  • 实例化建造者对象
  • 构造对象
  • 序列化 & 反序列化

序列化:

cpp 复制代码
#include <jsoncpp/json/json.h>

int main()
{
    Json::Value val;
    val["name"] = "DeepSeek-chat";
    val["desc"] = "一款实用性强,功能强大的聊天模型";
    val["model"] = "deepseek-3.5";
    val["apikey"] = "sk-xxxx";  
    val["baseurl"] = "https://api.deepseek.cn/v1";

    //1.实例化建造者对象
    Json::StreamWriterBuilder builder;
    Builder["indentation"]= "";
    //2.构造对象
    std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
    //3.序列化
    std::stringstream ss;
    int ret = writer->write(val, &ss);//返回0表示成功
    if(ret != 0){
        std::cout << "write json failed" << std::endl;
        return -1;
    }
    std::string str = ss.str();
    std::cout << str << std::endl;
    return 0;
}

可以加上下面,让输出变成紧凑单行格式(无缩进无换行)

cpp 复制代码
Builder["indentation"]= "";

反序列化动手:

cpp 复制代码
#include <jsoncpp/json/json.h>

int main()
{
    //R"() 代表原始字符串
    std::string str = R"({
        "name": "DeepSeek-chat",
        "desc": "DeepSeek-3.5",
        "model": ["deepseek-3.5", "deepseek-3.5-16k", "deepseek-3.5-8k"]
    })";

    Json::CharReaderBuilder Builder;
    std::unique_ptr<Json::CharReader> reader(Builder.newCharReader());
    Json::Value val;    
    std::string errs;
    bool ret = reader->parse(str.c_str(), str.c_str() + str.size(), &val, &errs);
    if(!ret){
        std::cout << "parse json failed, errs: " << errs << std::endl;
        return -1;
    }
    std::cout << val["name"].asString() << std::endl;
    std::cout << val["desc"].asString() << std::endl;
    if(val["model"].isArray()){
        for(int i = 0; i < val["model"].size(); i++){
            std::cout << val["model"][i].asString() << std::endl;
        }
    }
}

📢写在最后

相关推荐
一晌小贪欢14 分钟前
python-第20天:关键字参数与不定长参数
java·开发语言·前端·python·数据可视化·函数参数·python办公
小灰灰搞电子15 分钟前
Rust+Slint 实现蜂巢菜单源码分享
开发语言·rust·蜂巢菜单.
我命由我1234516 分钟前
JS Mock(Mock 拦截请求的前提、Mock 使用、关闭 Mock)
开发语言·前端·javascript·前端框架·html·html5·js
console.log('npc')20 分钟前
火山引擎 Ark 平台模型部署与计费配置文档
网络·火山引擎
昌原的儿子LEO21 分钟前
Linux网络编程:TCP/UDP与HTTP协议核心笔记
linux·网络·tcp/ip
OPEN-F23 分钟前
C++并发编程:异步任务与线程池实战
开发语言·c++·算法
南大白25 分钟前
IDEA Maven+JDK 全局配置 日志记录
java·maven·intellij-idea
好评12425 分钟前
【Linux】应用层协议HTTP
linux·运维·http