目录
引言
一.JSON简介
二. Jsoncpp库概述
三. Jsoncpp核心类介绍
3.1 Json::Value类
3.2 序列化与反序列化类
四. 实现序列化
五. 实现反序列化
结语
引言
在现代软件开发中,数据交换格式扮演着至关重要的角色。JSON(JavaScript Object Notation)以其简洁、易于阅读和支持多种数据类型的特点,成为了数据交换领域的明星。本文将深入探讨JSON的基本概念、数据类型以及如何使用Jsoncpp库实现JSON的序列化与反序列化。
一.JSON简介
JSON是一种轻量级的数据交换格式,它基于文本,易于人阅读和编写,同时也易于机器解析和生成。JSON的数据结构包括以下几种:
- 对象:由花括号
{}
包围,存储键值对。- 数组:由中括号
[]
包围,存储有序集合。- 字符串:由双引号
""
包围。- 数字:整数或浮点数。
- 布尔值:
true
或false
。- null:表示空值。
例:⼩明同学的学⽣信息
char name = "⼩明";
int age = 18;
float score[3] = {88.5, 99, 58};
则json这种数据交换格式是将这多种数据对象组织成为⼀个字符串:
[
{
"姓名" : "⼩明",
"年龄" : 18,
"成绩" : [88.5, 99, 58]
},
{
"姓名" : "⼩⿊",
"年龄" : 18,
"成绩" : [88.5, 99, 58]
}
]
二. Jsoncpp库概述
Jsoncpp是一个流行的C++库,用于处理JSON数据。它提供了序列化和反序列化的机制,使得在C++程序中生成和解析JSON数据变得简单。
三. Jsoncpp核心类介绍
// Json数据对象类
class Json::Value
{
Value &operator=(const Value &other); // Value重载了[]和=,因此所有的赋值和获取数据都可以通过
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();
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
bool asBool() const; // 转 bool
};
// 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;
}
// 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;
}
3.1 Json::Value类
Json::Value
类是Jsoncpp中表示JSON数据的核心类。它提供了一系列的方法来操作JSON数据:
operator[]
:通过键名或数组索引访问数据。asString
、asInt
、asFloat
、asBool
:将JSON数据转换为相应的C++数据类型。append
:向JSON数组中添加元素。
3.2 序列化与反序列化类
序列化是将JSON对象转换为字符串的过程,反序列化则是相反的过程。Jsoncpp提供了以下类来实现这些功能:
StreamWriter
和StreamWriterBuilder
:用于创建序列化器,将Json::Value
对象转换为JSON格式的字符串。CharReader
和CharReaderBuilder
:用于创建反序列化器,将JSON格式的字符串解析为Json::Value
对象。
四. 实现序列化
下面是一个使用Jsoncpp实现序列化的示例:
#include <jsoncpp/json/json.h>
#include <iostream>
#include <sstream>
#include <memory>
int main() {
const char* name = "小明";
int age = 19;
float score[] = {77.5, 88, 99.5};
Json::Value val;
val["姓名"] = name;
val["年龄"] = age;
val["成绩"] = Json::Value(Json::arrayValue);
for (float s : score) {
val["成绩"].append(s);
}
Json::StreamWriterBuilder swb;
std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
std::stringstream ss;
// 检查sw是否为空指针
if (!sw) {
std::cerr << "Failed to create StreamWriter" << std::endl;
return -1;
}
try {
int result = sw->write(val, &ss);
if (result != 0) { // 检查是否有错误
std::cerr << "Write failed with error code: " << result << std::endl;
} else {
std::cout << ss.str() << std::endl;
}
} catch (const std::exception& e) {
std::cerr << "Exception occurred: " << e.what() << std::endl;
return -1;
}
return 0;
}
五. 实现反序列化
下面是一个使用Jsoncpp实现反序列化的示例:
#include <jsoncpp/json/json.h>
#include <iostream>
#include <string>
int main()
{
std::string str = R"({"姓名":"小明", "年龄":18, "成绩":[76.5, 55, 88]})";
Json::Value root;
Json::CharReaderBuilder crb;
std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
std::string err;
if (!cr->parse(str.c_str(), str.c_str() + str.size(), &root, &err))
{
std::cout << "Parse error: " << err << std::endl;
}
else
{
std::cout << "Name: " << root["姓名"].asString() << std::endl;
std::cout << "Age: " << root["年龄"].asInt() << std::endl;
int sz = root["成绩"].size();
for (int i = 0; i < sz; i++)
{
std::cout << "Score: " << root["成绩"][i].asFloat() << std::endl;
}
}
return 0;
}
结语
JSON作为一种灵活的数据交换格式,结合Jsoncpp库,为C++开发者提供了强大的数据交换能力。无论是网络通信还是数据存储,JSON和Jsoncpp都是你的理想选择。通过本文的介绍,希望你能对JSON和Jsoncpp有一个全面的了解,并能将其应用到实际开发中。