Json Jsoncpp

文章目錄

  • Json 介紹
  • Jsoncpp 介紹
    • Json::Value
    • 序列化接口
    • 反序列化接口
  • 序列化操作
  • 反序列化操作


?
?
?

Json 介紹


JSON(JavaScript Object Notation,JavaScript 對象表示法)是一種輕量級的數據交換格式,具有簡潔、易讀、跨平臺等特點,廣泛應用于前后端數據傳輸、配置文件、API 接口等場景。

核心特點:

  • 文本格式:基于純文本,易于人類閱讀和編寫,也便于機器解析和生成。
  • 跨語言兼容:雖然源于 JavaScript,但幾乎所有編程語言都有解析和生成 JSON 的庫(如 Python 的 json 模塊、Java 的 Jackson 等)。
  • 數據結構簡單:僅支持兩種核心結構:
    • 鍵值對集合(類似對象、字典):用 {} 包裹,鍵值對以 : 分隔,格式為 {"key": value}
    • 有序值列表(類似數組):用 [] 包裹,元素以 , 分隔,格式為 [value1, value2, ...]
  • 支持的數據類型:字符串(“string”)、數字(整數 / 浮點數,如 123、3.14)、布爾值(true/false)、null、對象、數組。

Json數據格式:

{"name": "Alice","age": 25,"is_student": false,"hobbies": ["reading", "coding"],"address": {"city": "Beijing","street": "Main St"}
}

?
?

Jsoncpp 介紹


Jsoncpp 是一個用于 C++ 語言的 JSON 解析庫,提供了對 JSON 數據的讀寫、解析和生成功能,是 C++ 開發中處理 JSON 的常用工具。

核心功能

  • 解析 JSON 字符串 / 文件:將 JSON 格式的文本轉換為 C++ 可操作的對象。
  • 生成 JSON 字符串 / 文件:將 C++ 中的數據結構轉換為 JSON 格式。
  • 操作 JSON 數據:支持增刪改查 JSON 中的鍵值對、數組元素等。

主要類和方法

  • Json::Value:最核心的類,用于表示 JSON 中的值(可以是對象、數組、字符串、數字等)。

    • 示例:Json::Value root; root["name"] = "Alice";(創建鍵值對)
  • Json::FastWriter / Json::StyledWriter:用于將 Json::Value 轉換為 JSON 字符串。(這是舊版序列化接口,這里寫出來給大家見一見,我們學習使用還是選擇新版的)

    • FastWriter:生成緊湊的無縮進字符串。
    • StyledWriter:生成帶縮進的易讀字符串。
  • Json::Reader:用于解析 JSON 字符串或文件,將其轉換為 Json::Value 對象。(這是舊版反序列化接口,這里寫出來給大家見一見,我們學習使用還是選擇新版的)

    • 示例:Json::Reader reader; reader.parse(json_str, root);(解析字符串到 root)

Jsoncpp 庫主要借助三個類以及其對應的少量成員函數完成序列化和反序列化

Json::Value

我們先來看一下 Json 數據對象類的表示(只列舉了部分重要的接口):

class Json::Value {// 賦值運算符重載:將另一個Value對象的值賦給當前對象Value &operator=(const Value &other);// 鍵值對操作:通過字符串鍵獲取/設置值// 示例:val["name"] = "xx"; (設置)或 std::string name = val["name"].asString();(獲取)Value& operator[](const std::string& key);Value& operator[](const char* key);// 移除指定鍵的成員Value removeMember(const char* key);// 數組操作:通過索引獲取數組元素(常量版本)// 示例:int firstScore = val["score"][0].asInt();const Value& operator[](ArrayIndex index) const;// 向數組末尾添加元素// 示例:val["score"].append(88);Value& append(const Value& value);// 獲取數組元素個數// 示例:int scoreCount = val["score"].size();ArrayIndex size() const;// 類型轉換方法std::string asString() const;      // 轉換為std::string,示例:std::string name = val["name"].asString();const char* asCString() const;     // 轉換為C風格字符串,示例:const char* name = val["name"].asCString();Int asInt() const;                 // 轉換為整數,示例:int age = val["age"].asInt();float asFloat() const;             // 轉換為浮點數,示例:float weight = val["weight"].asFloat();bool asBool() const;               // 轉換為布爾值,示例:bool ok = val["ok"].asBool();
};
  • Json::Value 是 Jsoncpp 庫中最核心的類,如果要將數據對象進行序列化,就需要先存儲到 Json::Value 對象中。
  • 如果要將一個 Json 數據串進行反序列化(就是解析完成后),也需要將數據放到Json::Value 對象中。

簡單來說,它是 JSON 數據在 C++ 中的 “容器” 和 “操作接口”,所有對 JSON 的創建、修改、訪問都通過這個類完成。

?
?

序列化接口

// JSON_API 是 Jsoncpp 中用于導出類的宏(跨平臺兼容)
// StreamWriter 是一個純虛基類,定義了 JSON 寫入流的接口
class JSON_API StreamWriter {
public:// 純虛函數:將 JSON 數據(root)寫入輸出流(sout)// 返回值:寫入的字符數(成功)或負數(失敗)virtual int write(Value const& root, std::ostream* sout) = 0;// 虛析構函數(基類通常需要定義,確保派生類析構正確)virtual ~StreamWriter() = default;
};// StreamWriterBuilder 是 StreamWriter 的工廠類
// 繼承自 StreamWriter::Factory(工廠接口)
class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
public:// 工廠方法:創建并返回一個 StreamWriter 實例// 用于將 Json::Value 轉換為 JSON 字符串并寫入流virtual StreamWriter* newStreamWriter() const;// 虛析構函數virtual ~StreamWriterBuilder() = default;
};

?
?

反序列化接口

// JSON_API 宏導出宏,用于跨平臺動態鏈接
// CharReader 是純虛基類,定義了解析JSON字符串的接口
class JSON_API CharReader {
public:// 純虛函數:解析JSON字符串并填充到Value對象// 參數://   beginDoc - JSON字符串的起始地址//   endDoc   - JSON字符串的結束地址(指向最后一個字符的下一位)//   root     - 輸出參數,解析后的JSON數據將存儲到該Value對象//   errs     - 輸出參數,解析錯誤信息(若解析失敗)// 返回值:true表示解析成功,false表示失敗virtual bool parse(char const* beginDoc, char const* endDoc,Value* root, std::string* errs) = 0;// 虛析構函數,確保派生類析構函數能正確調用virtual ~CharReader() = default;
};// CharReaderBuilder 是CharReader的工廠類
// 繼承自CharReader::Factory(工廠接口)
class JSON_API CharReaderBuilder : public CharReader::Factory {
public:// 工廠方法:創建并返回一個CharReader實例// 用于解析JSON字符串為Json::Value對象virtual CharReader* newCharReader() const;// 虛析構函數virtual ~CharReaderBuilder() = default;
};

?
?

序列化操作


前面已經介紹過接口了,所以這里直接演示使用方式:

#include <iostream>
#include <string>
#include <memory>
#include <sstream>
#include <jsoncpp/json/json.h>
using namespace std;// 實現數據的序列化
void serialize(const Json::Value& value, string& output) 
{std::stringstream ss;// 先實例化一個工廠類Json::StreamWriterBuilder writer;// 通過工廠類創建一個流寫入器std::unique_ptr<Json::StreamWriter> jsonWriter(writer.newStreamWriter());// 將數據寫入到字符串流中jsonWriter->write(value, &ss);// 獲取字符串流中的內容output = ss.str();
}int main()
{std::string name = "小明";int age = 18;std::string sex = "男";double score[3] = {63, 78.5, 87};// 創建一個Json對象Json::Value fav;fav["書籍"] = "三國演義";fav["運動"] = "籃球";fav["音樂"] = "探窗";Json::Value student;student["姓名"] = name;student["年齡"] = age;student["性別"] = sex;student["成績"] = Json::arrayValue; // 創建一個數組for (int i = 0; i < 3; ++i) {student["成績"].append(score[i]); // 向數組中添加元素}student["愛好"] = fav;// 序列化Json對象std::string output;serialize(student, output);std::cout << "Serialized JSON: \n" << output << std::endl;return 0;
}

在這里插入圖片描述

?
?

反序列化操作


#include <iostream>
#include <string>
#include <memory>
#include <sstream>
#include <jsoncpp/json/json.h>
using namespace std;// 實現數據的反序列化
void unserialize(const std::string& input, Json::Value& value) 
{// 實例化工廠類Json::CharReaderBuilder readerBuilder;// 創建解析器std::unique_ptr<Json::CharReader> jsonReader(readerBuilder.newCharReader());// 直接使用input解析,無需經過stringstream中轉std::string errs;if (!jsonReader->parse(input.c_str(), input.c_str() + input.size(), &value, &errs)) {std::cerr << "Failed to parse JSON: " << errs << std::endl;}
}int main()
{std::string input = R"({"姓名": "小明","年齡": 18,"性別": "男","成績": [63, 78.5, 87],"愛好": {"書籍": "三國演義","運動": "籃球","音樂": "探窗"}})";Json::Value student;// 反序列化Json字符串unserialize(input, student);// 輸出各個字段std::cout << "姓名: " << student["姓名"].asString() << std::endl;std::cout << "年齡: " << student["年齡"].asInt() << std::endl;std::cout << "性別: " << student["性別"].asString() << std::endl;std::cout << "成績: ";for (Json::ArrayIndex i = 0; i < student["成績"].size(); ++i) {  // 更規范的數組遍歷方式std::cout << student["成績"][i].asDouble() << " ";}std::cout << std::endl;std::cout << "愛好: \n";std::cout << "  書籍: " << student["愛好"]["書籍"].asString() << std::endl;std::cout << "  運動: " << student["愛好"]["運動"].asString() << std::endl;std::cout << "  音樂: " << student["愛好"]["音樂"].asString() << std::endl;return 0;
}

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/91660.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/91660.shtml
英文地址,請注明出處:http://en.pswp.cn/web/91660.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

openwrt下安裝istore(基于pve)

openwrt下安裝istore&#xff08;基于pve&#xff09;ssh連接到openwrt&#xff0c;用如下命令安裝istore&#xff1a;opkg update || exit 1cd /tmpwget https://github.com/linkease/openwrt-app-actions/raw/main/applications/luci-app-systools/root/usr/share/systools/i…

2025年Python Web框架之爭:Django、Flask還是FastAPI,誰將主宰未來?

文章概要 作為一名Python開發者&#xff0c;我經常被問到同一個問題&#xff1a;在2025年&#xff0c;Django、Flask和FastAPI哪個框架更值得使用&#xff1f;隨著技術的快速發展&#xff0c;這個問題的答案也在不斷變化。本文將全面比較這三個主流Python Web框架的特點、性能、…

高級11-Java日志管理:使用Log4j與SLF4J

在現代Java應用開發中&#xff0c;日志&#xff08;Logging&#xff09;是系統監控、調試、故障排查和性能分析的核心工具。一個高效、靈活、可配置的日志系統&#xff0c;不僅能幫助開發者快速定位問題&#xff0c;還能為運維團隊提供寶貴的運行時信息。在Java生態系統中&…

sc-atac的基礎知識(0)

sc-atac的基礎知識 **fragment**是ATAC-seq實驗中的一個重要概念&#xff0c;它指的是通過Tn5轉座酶對DNA分子進行酶切&#xff0c;然后經由雙端測序得到的序列。根據Tn5插入導致的偏移從read比對得到的位置推斷出fragment的起始和結束位置。根據之前的報道&#xff0c;Tn5轉座…

Python從入門到精通計劃Day01: Python開發環境搭建指南:從零開始打造你的“數字廚房“

目錄一、配置你的「魔杖」&#xff1a;Python 3.x安裝1.1 跨平臺安裝指南1.2 驗證你的「法力值」二、選擇你的「魔法工坊」&#xff1a;IDE配置2.1 VS Code&#xff1a;輕量級實驗室2.2 PyCharm&#xff1a;專業級法師塔三、施展第一個「魔咒」&#xff1a;Hello World3.1 基礎…

MCP Agent 工程框架Dify初探

目錄引言一、Dify是什么二、為什么使用Dify三、使用Dify要怎么做1、聊天助手2、Agent2.1 Function calling&#xff08;函數調用&#xff09;和 ReAct 兩種推理模式的區別2.1.1 技術本質與工作流程對比2.1.2 優缺點對比2.1.3 適用場景與選擇依據2.2 LangChain 的 Agent 實現原理…

無人機光伏巡檢漏檢率↓78%!陌訊多模態融合算法實戰解析

原創聲明本文為原創技術解析&#xff0c;核心技術參數與架構設計引用自《陌訊技術白皮書》&#xff0c;轉載請注明來源。一、行業痛點&#xff1a;無人機光伏巡檢的 "識別困境"光伏電站的大規模鋪設推動了無人機巡檢的普及&#xff0c;但實際作業中仍面臨三大技術瓶頸…

機動車占道識別準確率提升 29%:陌訊動態輪廓感知算法實戰解析

原創聲明本文為原創技術解析&#xff0c;核心技術參數與架構設計引用自《陌訊技術白皮書》&#xff0c;禁止未經授權的轉載與改編。一、行業痛點&#xff1a;機動車占道治理的技術瓶頸城市交通監控中&#xff0c;機動車占用應急車道、公交車道等違規行為已成為影響通行效率與交…

UNet改進(29):記憶增強注意力機制在UNet中的創新應用-原理、實現與性能提升

記憶增強注意力機制概述 記憶增強注意力是一種結合了外部記憶模塊的注意力機制,它使神經網絡能夠存儲和檢索長期知識,而不僅僅是依賴當前的輸入特征。這種機制特別適合需要保持長期依賴關系的任務,如醫學圖像分割,其中模型需要記住不同樣本中出現的常見模式。 核心組件 記…

使用Python開發Ditto剪貼板數據導出工具

前言在日常工作中&#xff0c;我們經常需要處理大量的剪貼板數據。Ditto作為一款優秀的剪貼板管理軟件&#xff0c;幫助我們保存了豐富的歷史記錄。但有時我們需要將這些數據導出進行進一步分析或備份&#xff0c;而Ditto本身并沒有提供直觀的批量導出功能。C:\pythoncode\new\…

【人工智能】提示詞設計原則:簡潔性、明確性、具體性如何平衡?

提示詞設計原則&#xff1a;簡潔性、明確性、具體性如何平衡&#xff1f;1. 提示詞設計三大原則的核心內涵1.1 簡潔性1.1.1 定義用最少的文字傳遞核心信息&#xff0c;避免冗余和不必要的描述。比如 “寫 3 個春天的成語” 比 “我想讓你寫出來 3 個和春天有關系的成語詞語” 更…

JS的作用域

文章目錄一、為什么需要作用域&#xff1f;二、什么是 JS 作用域&#xff1f;2.1 什么是詞法作用域和動態作用域&#xff1f;1. 詞法作用域&#xff08;Lexical Scpoe&#xff09;2. 動態作用域2.2 JS 的作用域2.3 JS 作用域的分類1. 全局作用域2. 模塊作用域3. 函數作用域4. 塊…

OLTP,OLAP,HTAP是什么,數據庫該怎么選

目錄 OLTP&#xff08;Online Transaction Processing&#xff09;聯機事務處理 OLAP&#xff08;Online Analytical Processing&#xff09;聯機分析處理 非實時OLAP 實時OLAP HTAP&#xff08;Hybrid Transactional/Analytical Processing&#xff09; OLAP 和 OLTP 數…

【前端】CSS Flexbox布局示例介紹

CSS Flexbox&#xff08;彈性盒子&#xff09;簡介 Flexbox 是一種一維布局模型&#xff0c;用于高效處理元素在容器內的空間分配、對齊和排序。它通過父容器&#xff08;flex container&#xff09;和子元素&#xff08;flex items&#xff09;的配合實現靈活響應式布局。核心…

Vue3核心語法基礎

一、為什么要學 Composition API&#xff1f;在以前我們寫代碼用Vue2寫&#xff1a;export default {data() {return { count: 0, msg: hello }},methods: {add() { this.count }},computed: {double() { return this.count * 2 }} }很明顯 一個功能被拆成三塊&#xff1a;data…

FSMC的配置和應用

一、FSMC 簡介與工作原理FSMC&#xff08;Flexible Static Memory Controller&#xff09;是 STM32 微控制器中用于與外部靜態存儲器&#xff08;如 SRAM、PSRAM、NOR Flash、LCD 等&#xff09;進行通信的一個外設模塊。1、支持的設備類型&#xff1a;SRAM / PSRAMNOR FlashNA…

Linux I/O 系統調用完整對比分析

Linux I/O 系統調用完整對比分析 1. 概述 Linux 提供了豐富的 I/O 系統調用&#xff0c;每種都有其特定的用途和優勢。本文將詳細分析這些系統調用的特點、使用場景和性能特征。 2. 系統調用詳細對比 2.1 基本讀寫函數 pread/pwrite #include <unistd.h>// 位置指定…

TiDB集群部署

架構&#xff1a; tidb–3臺&#xff0c;pd–3臺&#xff0c;tikv–3臺 8c16g200g 1x2.2x.2x7.124 1x2.2x.2x7.148 1x2.2x.2x7.87 1x2.2x.2x7.93 1x2.2x.2x7.127 1x2.2x.2x7.104 pd-3臺 4c8g100g 1x2.2x.2x7.143 1x2.2x.2x7.132 1x2.2x.2x7.91 1、下載安裝包 #注&#xff1a;我…

C#中對于List的多種排序方式

在 C# 中給 List<AI> 排序&#xff0c;只要 明確排序規則&#xff08;比如按某個字段、某幾個字段、或外部規則&#xff09;&#xff0c;就能用下面幾種常見寫法。下面全部基于這個示例類&#xff1a;public class AI {public int country; // 國家編號public int pr…

Spring框架中Bean的生命周期:源碼解析與最佳實踐

第1章&#xff1a;Spring Bean生命周期概述1.1 什么是Spring Bean生命周期&#xff1f;定義&#xff1a;Spring Bean生命周期是指從Bean的創建、初始化、使用到銷毀的完整過程&#xff0c;由Spring容器嚴格管理 。核心思想是Spring容器通過IoC&#xff08;控制反轉&#xff09;…