【C++】Json库介绍和使用

JsonCpp库

Json数据格式

Json 是一种数据交换格式,它采用完全独立于编程语言的文本格式来存储和表示数据。

例如:我们想表示一个同学的学生信息

C代码表示

cpp 复制代码
char *name = "xx";
int age = 18;
float score[3] = {88.5,99,58];

Json表示

cpp 复制代码
{
    "姓名" : "xx",
    "年龄" : 18,
    "成绩" : {88.5,99,58},
    "爱好" : {
        "书籍" : "西游记",
        "运动" : "打游戏"
    }
}

Json 的数据类型包括对象,数组,字符串,数字等

  • 对象:使用花括号 { } 括起来的表示一个对象
  • 数组:使用中括号 亏括起来的表示一个数组
  • 字符串:使用常规双引号 " " 括起来的表示一个字符串
  • 数字:包括整形和浮点型,直接使用

Jsoncpp介绍

Jsoncpp 库主要是用于实现 Json 格式数据的序列化和反序列化,它实现了将多个数据对象组织成为 Json 格式字符串,以及将 Json 格式字符串解析多个数据对象的功能

先看一下 Json 对象类的表示

cpp 复制代码
class Json::Value {
    Value &operator=(const Value &other); // Value重载了[]和=,因此所有的赋值和获取数据都可以通过
    Value& operator[](const std::string& key); // 简单的方式完成 val["name"] = "xx";
    Value& operator[](const char* key);
    Value removeMember(const char* key); // 移除元素
    const Value& operator[](ArrayIndex index) const; // val["score"][0]
    Value& append(const Value& value); // 添加数组元素 val["score"].append(88);
    ArrayIndex size() const; // 获取数组元素个数 val["score"].size();
    std::string asString() const; // 转string string name = val["name"].asString();
    const char* asCString() const; // 转char* char *name = val["name"].asCString();
    Int asInt() const; // 转int int age = val["age"].asInt();
    float asFloat() const; // 转float float weight = val["weight"].asFloat();
    bool asBool() const; // 转 bool bool ok = val["ok"].asBool();
};

Jsoncpp 主要借助三个类以及对应的少量成员函数完成序列化和反序列化

1.序列化接口

cpp 复制代码
class JSON_API StreamWriter {
    virtual int write(Value const& root, std::ostream* sout) = 0;
}
class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
    virtual StreamWriter* newStreamWriter() const;
}

2.反序列化接口

cpp 复制代码
class JSON_API CharReader {
    virtual bool parse(char const* beginDoc, char const* endDoc, 
                       Value* root, std::string* errs) = 0;
}
class JSON_API CharReaderBuilder : public CharReader::Factory {
    virtual CharReader* newCharReader() const;
}

Jsoncpp 使用

cpp 复制代码
#include <iostream>
#include <sstream>
#include <string>
#include <jsoncpp/json/json.h>
#include <memory>

// 实现数据的序列化
bool serialize(const Json::Value &val, std::string &body)
{
    
    std::stringstream ss;
    // 先实例化一个工厂类对象
    Json::StreamWriterBuilder swb;

    swb["emitUTF8"] = true; 

    // 通过工厂类对象来生产派生类对象
    std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
    int ret = sw->write(val, &ss);

    if(ret != 0){
        std::cout << "Json serialize failed!\n";
        return false;
    }

    // std::cout << std::endl;
    body = ss.str();
    return true;
}

// 实现json字符串的反序列化
bool unserialize(const std::string &body, Json::Value &val)
{
    // 实例化工厂类对象
    Json::CharReaderBuilder crb;
    // 生产CharReader对象
    std::string errs;
    std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
    bool ret = cr->parse(body.c_str(), body.c_str() + body.size(), &val, &errs);
    if(ret == false){
        std::cout << "json unserialize failed : " << errs <<std::endl;
        return false;
    }
    return true;
}

int main()
{

    const char *name = "小明";
    int age = 18;
    const char *sex = "男";
    float score[3] = {88, 77.5, 66};

    Json::Value student;
    student["姓名"] = name;
    student["年龄"] = age;
    student["性别"] = sex;
    student["成绩"].append(score[0]);
    student["成绩"].append(score[1]);
    student["成绩"].append(score[2]);

    Json::Value fav;
    fav["书籍"] = "西游记";
    fav["运动"] = "打篮球";
    student["爱好"] = fav;
    std::string body;
    serialize(student, body);
    std::cout << body << std::endl;

    std::string str = R"({"姓名":"小黑", "年龄":19, "成绩":[32, 45, 56]})";
    Json::Value stu;
    bool ret = unserialize(str,stu);
    if(ret == false) return -1;
    std::cout << "姓名: " << stu["姓名"].asString() << std::endl;
    std::cout << "年龄: " << stu["年龄"].asInt() << std::endl; 
    int sz = stu["成绩"].size();
    for(int i = 0;i < sz; i++){
        std::cout << "成绩: " << stu["成绩"][i].asFloat() << std::endl;
    }

    return 0;
}
相关推荐
weixin_3077791320 分钟前
C++代码实现MATLAB中的fitrtree函数功能
开发语言·c++·算法·matlab
AI wins24 分钟前
c++新增頭文件
c++
Shadow(⊙o⊙)34 分钟前
仿muduo实现高并发服务器——事件就绪管理Channel.hpp
服务器·c++
by2099944 分钟前
哈希表——快速找到数据:冲突、删除与扩容的实现
数据结构·c++·哈希算法·散列表
音草2 小时前
C++ 继承详解:从概念到菱形继承
c++
weixin_307779132 小时前
C++代码实现MATLAB中的spectralcluster函数功能
开发语言·c++·算法·matlab
xiaoye-duck2 小时前
《C++ 项目:手写大模型接入 SDK》Trae IDE 开发环境搭建与依赖管理
c++·ide·语言模型
沫璃染墨3 小时前
《Qt从零入门系列(十四):QThread多线程详解——从线程创建到客户端阻塞处理》
开发语言·c++·笔记·qt·ui·交互·线程
草莓熊Lotso3 小时前
【C++ 基于微服务的即时通讯系统】Elasticsearch 从安装到 C++ 客户端二次封装全落地
linux·网络·数据库·c++·elasticsearch·微服务
CHPCWWHSU3 小时前
FreeCAD 源码解读:从 Property 到 Command,看一套 CAD 内核的完整闭环
c++·cad