【C++】JsonCpp库

目录

前置知识

Json数据格式

JsonCpp介绍

安装jsoncpp库

头文件

使用介绍

使用示例

序列化

反序列化


前置知识

Json数据格式

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

例如:表示一个学生信息

{

"姓名":"xxx",

"年龄":18,

"成绩":[88.5,99,58]

}

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

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

JsonCpp介绍

安装jsoncpp库

Linux环境下(ubuntu)

sudo apt-get install libjsoncpp-dev

头文件

在使用前,需要先引入jsoncpp的头文件

#include<jsoncpp/json/json.h>

使用介绍

JsonCpp库是用来实现Json数据格式的序列化和反序列化,主要涉及三个类:

1、Json::Value类:中间数据存储类

如果要将数据进行序列化,就需要先存储到Json::Value对象中;

如果要将数据进行反序列化,就是解析后,将数据对象放入到Json::Value对象中

如下是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();
};

2、序列化接口

  • Json::StreamWriter类:用于进行数据序列化
  • Json::StreamWriter::write() 序列化函数
  • Json::StreamWriterBuilder类:Json::StreamWriter工厂类,用于生产一个Json::StreamWriter对象
cpp 复制代码
class JSON_API StreamWriter {
     virtual int write(Value const& root, std::ostream* sout) = 0;
}
//工厂类,生成一个StreamWriter对象
class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
     virtual StreamWriter* newStreamWriter() const;
}

PS:

virtual int write(要序列化的Json::Value对象, 输出流对象地址) = 0;

  • 返回0序列化成功

3、反序列接口

  • Json::CharReader反序列化类
  • Json::CharReader::parse()反序列化函数
  • Json::CharReaderBuilder 工厂类,用于生产一个Json::CharReader对象
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;
}

PS:

virtual bool parse((序列化后的字符串)字符串的起始地址, 字符串的结束地址,存放解析结果的Json::Value对象的地址,erro信息)

  • 返回true反序列化成功

使用示例

序列化

cpp 复制代码
#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include <jsoncpp/json/json.h>
bool serialize(Json::Value &val,std::string &body)
{
    std::stringstream ss;
    //先实例化一个工厂类对象
    Json::StreamWriterBuilder swb;
    //获取一个StreamWriter对象
    std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
    int ret=sw->write(val,&ss);
    if(ret!=0)
    {
        std::cout<<"serialize failed!"<<std::endl;
        return false;
    }

    body=ss.str();
    return true;
    
}
int main()
{
    Json::Value student;
    Json::Value fav;//描述爱好
    //填入爱好
    fav["书籍"]="骆驼祥子";
    fav["运动"]="打羽毛球";


    student["姓名"]="张三";
    student["年龄"]=19;
    //数组不能直接赋值,需要使用append方法
    student["成绩"].append(100);
    student["成绩"].append(100);
    student["成绩"].append(100);
    //嵌套一个对象
    student["爱好"]=fav;

    std::string body;
    if(serialize(student,body))
    {
        std::cout<<body<<std::endl;
    }

    return 0;
}

编译运行

g++ -std=c++11 jsoncpp_test.cc -o json -ljsoncpp

结果如下:

bash 复制代码
root@ubuntu:~/demo/jsoncpp# ./json 
{
        "姓名" : "张三",
        "年龄" : 19,
        "成绩" : 
        [
                100,
                100,
                100
        ],
        "爱好" : 
        {
                "书籍" : "骆驼祥子",
                "运动" : "打羽毛球"
        }
}

注意:

  • Json::StreamWriterBuilder工厂类返回的是Json::StreamWriter的指针,因此我们使用完Json::StreamWriter对象后要记得释放,这里采用智能指针对其进行管理。

反序列化

cpp 复制代码
bool unserialize(const std::string &body,Json::Value &val)
{
    //创建Json::CharReaderBuilder 工厂类
    Json::CharReaderBuilder crb;
    //获取一个Json::CharReader对象
    std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
    std::string errs;
    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()
{
  
    std::string str=R"({"姓名":"张三","年龄":19,"成绩":[100,100,99]})";
    Json::Value val;
    if(unserialize(str,val))
    {
        std::cout<<"姓名:"<<val["姓名"].asString()<<std::endl;
        std::cout<<"年龄:"<<val["年龄"].asInt()<<std::endl;
        int sz=val["成绩"].size();

        for(int i=0;i<sz;i++)
        {
            std::cout<<"成绩:"<<val["成绩"][i].asFloat()<<std::endl;
        }
    }
    return 0;
}
相关推荐
小高Baby@16 分钟前
网络授时笔记
开发语言·笔记·学习·php
誓约酱20 分钟前
git的基本使用
linux·运维·服务器·c++·git·后端
范纹杉想快点毕业21 分钟前
XML通过HTTP POST 请求发送到指定的 API 地址,进行数据回传
xml·c语言·开发语言·数据结构·c++·python·c#
黑客老陈23 分钟前
BaseCTF scxml 详解
开发语言·网络·python·sql·安全·web安全
Yang-Never27 分钟前
Kotlin->Kotlin协程的取消机制
android·java·开发语言·kotlin·android studio·idea
float_六七41 分钟前
C/C++头文件locale
c语言·开发语言·c++
LixiSchool1 小时前
Unity XML和Json文件的读取和写入以及序列化和反序列化
xml·json
不会玩技术的技术girl1 小时前
获取淘宝商品详情高级版 API 接口 Java 示例代码
java·开发语言·前端
誓约酱1 小时前
Linux下字符设备驱动编写(RK3568)
linux·运维·服务器·c语言·c++·嵌入式硬件·物联网
月亮有痕迹诶1 小时前
找到一个或多个多重定义的符号的问题
c++