首页 前端知识 C 第三方库【JSON】— jsoncpp

C 第三方库【JSON】— jsoncpp

2024-08-21 10:08:07 前端知识 前端哥 282 476 我要收藏

目录

认识JSON

jsoncpp库 安装&使用

认识jsoncpp

Json::Value

jsoncpp序列化

jsoncpp反序列化


认识JSON

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于编程语言的文本格式来存储和表示数据,常用于在客户端和服务器之间传输数据。

JSON由键值对组成,键必须是字符串,而值可以是字符串,布尔值,数组,对象或null

以下是一个简单的额JSON实例

在C/C++中,学生信息存储如下:

//在C/C++中,小明的信息如下
const char* name = "小明";
int age = 18;
float score[3] = {84.5, 90.5, 87};

 使用JSON存储学生信息如下:

{
        "姓名" : "小明",
        "年龄" : 18,
        "成绩" : [84.5, 90.5, 87]
}

json数据类型:对象,数组,字符串,数字,布尔值,null

对象:使用大括号{ }括起来

数组:使用中括号[ ]括起来

字符串:使用双引号" "括起来

数字:包括整型和浮点型,直接使用,都视为数组

键和值之间使用冒号:分隔,不同键值对之间使用逗号,分隔。数组也可以存储对象,如下:

[
   {
        "姓名" : "小明",
        "年龄" : 18,
        "成绩" : [84.5, 90.5, 87]
   },
   {
        "姓名" : "小黑",
        "年龄" : 17,
        "成绩" : [88.5, 93, 85]
   }
]

jsoncpp库 安装&使用

Linux下安装需执行如下指令

sudo yum install epel-release
udo yum install jsoncpp-devel

//如果成功查询到json的头文件和动静态库即为安装成功
//查看json中的头文件
[ljh@VM-12-11-centos practice]$ ls /usr/include/jsoncpp/json
assertions.h  autolink.h  config.h  features.h  forwards.h  json.h  reader.h  value.h  version.h  writer.h
 
//查看json的第三方库
[ljh@VM-12-11-centos practice]$ ls /usr/lib64/libjson*
/usr/lib64/libjsoncpp.so    /usr/lib64/libjsoncpp.so.0.10.5  /usr/lib64/libjson-c.so.2.0.1  /usr/lib64/libjson.so.0.1.0
/usr/lib64/libjsoncpp.so.0  /usr/lib64/libjson-c.so.2        /usr/lib64/libjson.so.0

使用时,包含头文件需要指明路径,gcc/g++默认查询的路径是/usr/include,而json.h的路径为/usr/include/jsoncpp/json/json.h。需包含头文件是#include <jsoncpp/json/json.h>

编译时需要链接jsoncpp库,需要加上-ljoncpp,如:

g++ -o test test.cc -std=c++11 -ljsoncpp

认识jsoncpp

jsoncpp是用于C++的JSON解析库,提供了简单易用的API来解析和生成JSON数据

最常用的是json格式的序列化和反序列化,完成将多个数据对象组织层json格式字符串,以及将json格式字符串解析得到多个数据对象的功能

Json::Value

Json::Value是JSON数据的通用类型。可以表示JSON对象,数组,字符串,数字,布尔值和null等各种类型

//Json数据对象类
class Json::Value{
    //Value重载了[]和=,因此所有的赋值和获取数据都可以通过
    Value &operator=(const Value &other); 
    Value& operator[](const std::string& key);//示例:val["姓名"] = "小明";
    Value& operator[](const char* key);
    //移除元素
    Value removeMember(const char* key);

    //访问数组元素
    const Value& operator[](ArrayIndex index) const; //示例:val["成绩"][0]
    //添加数组元素
    Value& append(const Value& value);//示例:val["成绩"].append(88); 
    //获取数组元素个数
    ArrayIndex size() const;//示例:val["成绩"].size();

    //访问数据,以string类型返回
    std::string asString() const;//示例:string name = val["name"].asString();
    //访问数据,以const char*类型返回
    const char* asCString() const;//示例:char *name = val["name"].asCString();
    //访问数据,以int类型返回
    Int asInt() const;//示例:int age = val["age"].asInt();
    //访问数据,以float类型返回
    float asFloat() const;
    //访问数据,以bool类型返回
    bool asBool() const;
};

jsoncpp序列化

序列化是将Json::Value转换成json格式的字符串

//json序列化类,低版本用这个更简单
class JSON_API Writer {
  virtual std::string write(const Value& root) = 0;
}
class JSON_API FastWriter : public Writer {
  virtual std::string write(const Value& root);
}
class JSON_API StyledWriter : public Writer {
  virtual std::string write(const Value& root);
}

//json序列化类,高版本推荐,如果用低版本的接口可能会有警告
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;
}

建议使用高版本。

  • StreamWriter类的write接口可以将Json::Value对象转换为Json格式的字符串,借由sout输出流传出
  • 由于StreamWriter是抽象类,不能直接定义对象,需要先定义StreamWriterBuilder对象,再通过newStreamWriter接口获取StreamWriter对象,再使用writer接口

示例

  1. 将所有数据保存在Json::Value对象中
  2. 使用StreamWriter的write接口,完成序列化
  3. 通过sout输出流获取json格式字符串
#include <iostream>
#include <memory>
#include <sstream>
#include <jsoncpp/json/json.h>

//测试序列化
void serialization()
{
    const char* name = "张三";
    int age = 26;
    float score[] = {84, 77.5, 88.3};
    //将所有数据保存到Json::Value中
    Json::Value root;
    root["姓名"] = name;
    root["年龄"] = age;
    //数组要使用append
    root["成绩"].append(score[0]);
    root["成绩"].append(score[1]);
    root["成绩"].append(score[2]);
    //序列化
    std::stringstream ss;
    Json::StreamWriterBuilder swb;
    std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
    sw->write(root, &ss);
    //通过输出流获取json格式字符串
    std::cout << ss.str() << std::endl;
}

int main()
{
    serialization();
    return 0;
}

通过打印显示json格式字符串

jsoncpp反序列化

反序列化是将json格式字符串转化成Json::Value对象,其中存储了各项数据

//json反序列化类,低版本用起来更简单
class JSON_API Reader {
 bool parse(const std::string& document, Value& root, bool collectComments = true);
}
//json反序列化类,高版本更推荐
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;
}

建议使用高版本。

  • CharReader中的parse实现反序列化逻辑:beginDoc和endDoc是需要转化的json格式字符串的起始地址和结束地址;root是输出型参数;如果反序列化出错,会返回false,并将错误信息存放在errs中
  • 同样,CharReader是抽象类,不能直接定义对象,借由CharReaderBuilder获取CharReader对象

示例

  1. 准备json格式字符串
  2. 获取CharReader对象,使用parse反序列化
  3. 通过转化类型接口打印Json::Value
#include <iostream>
#include <memory>
#include <sstream>
#include <jsoncpp/json/json.h>

//反序列化
void deserialization()
{
    //C++11新特性 R
    //R后的字符串,其中()括起来的任何字符都表示其本意,省略转义字符,如\就是字符\
    std::string str = R"({"姓名":"张三", "年龄":22, "成绩":[88, 78.4, 92.7]})";//Json字符串
    Json::Value root;//Json的Value
    Json::CharReaderBuilder crb;
    std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
    std::string err;//错误信息
    bool ret = cr->parse(str.c_str(), str.c_str() + str.size(), &root, &err);
    if(ret == false){
        std::cout << "Json CharReader 解析错误\n";
        exit(-1);
    }
    //打印Value信息
    std::cout << "姓名: " << root["姓名"].asString() << std::endl; 
    std::cout << "姓名: " << root["年龄"].asInt() << std::endl; 
    size_t len = root["成绩"].size();
    std::cout << "成绩: ";
    for(int i = 0; i < len; ++i)
        std::cout << root["成绩"][i] << " "; 
    std::cout << std::endl;
}

int main()
{
    deserialization();
    return 0;
}

转载请注明出处或者链接地址:https://www.qianduange.cn//article/16387.html
标签
评论
发布的文章

安装Nodejs后,npm无法使用

2024-11-30 11:11:38

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!