【從零實現JsonRpc框架#1】Json庫介紹

1.JsonCpp第三方庫

JSONCPP?是一個開源的 C++ 庫,用于解析和生成 JSON(JavaScript Object Notation)數據。它提供了簡單易用的接口,支持 JSON 的序列化和反序列化操作,適用于處理配置文件、網絡通信數據等場景。

2.Json 數據格式

JSON 是一種輕量級的數據交換格式,采用完全獨立于編程語言的文本格式來存儲和表示數據。

比如:我們想表示一個 同學的信息

C 代碼表示:

char *name = "xx";
int age = 18;
float score[3] = {88.5, 99, 58};

Json 表示:

{"姓名" : "xx","年齡" : 18,"成績" : [88.5, 99, 58],"愛好" :{"書籍" : "西游記","運動" : "打籃球"}
}

包含以下基本類型:

  • 對象(Object):鍵值對集合,用?{}?包裹,如?{"name": "Alice", "age": 25}
  • 數組(Array):有序值列表,用?[]?包裹,如?[1, "text", true]
  • 值(Value):可以是字符串、數字、布爾值、null、對象或數組。

在 JSONCPP 中,所有?JSON 數據均通過?Json::Value?類表示。

3.JsonCpp 介紹

Jsoncpp?庫主要是用于實現 Json 格式數據的序列化和反序列化,它實現了將多個數據對象組織成為 json 格式字符串,以及將 Json 格式字符串解析得到多個數據對象的功能。

先看一下 Json 數據對象類的表示

  • 功能:存儲任意 JSON 數據,支持動態類型判斷。
  • 常用方法
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(); // 判斷類型bool isObject() const;bool isArray() const;bool isString() const;
};

生成器(序列化接口 – Writer)

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::StreamWriterBuilder builder;
builder.settings_["indentation"] = "  "; // 縮進兩空格
std::string jsonStr = Json::writeString(builder, root);

解析器(反序列化接口–Reader)

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;
}
// 使用如下:
Json::CharReaderBuilder builder;
std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
JSONCPP_STRING errs;
bool success = reader->parse(jsonStr, jsonStr + strlen(jsonStr), &root, &errs);

小結,主要用的 三個類 如下:

  1. Json::Value類:中間數據存儲類

    • 就需要先存儲到?Json::Value?對象中如果要將數據對象進行序列化,如果要將數據傳進行反序列化,就是解析后,將數據對象放入到J?Json::Value?對象中
  2. Json::StreamWriter類:用于進行數據序列化

    • Json::StreamWriter::write()?序列化函數

    • Json::StreamWriterBuilder類: Json::StreamWriter?工廠類 – 用于生產?Json:.StreamWriter?對象

  3. Json::CharReader類:反序列化類

    • Json::CharReader::parse()?反序列化函數
    • Json::CharReaderBuilderJson::CharReader工廠類-用于生產?Json::.CharReader?對象

4.JsonCpp的使用

序列化(C++ 對象 -> JSON)

序列化是將 C++ 對象轉換為 JSON 格式的字符串。我們可以通過 Json::Value 類來構建 JSON 對象,然后使用 Json::StreamWriterJson::FastWriter 來生成 JSON 字符串。

#include <iostream>
#include <json/json.h>int main() {// 創建一個 Json::Value 對象Json::Value root;// 添加一些鍵值對root["name"] = "Alice";root["age"] = 30;root["is_student"] = false;// 創建一個數組Json::Value languages;languages.append("C++");languages.append("Python");languages.append("JavaScript");root["languages"] = languages;// 使用 FastWriter 將 Json::Value 轉換為 JSON 字符串Json::FastWriter fastWriter;std::string jsonString = fastWriter.write(root);// 輸出 JSON 字符串std::cout << "Serialized JSON: " << jsonString << std::endl;return 0;
}

序列化結果

Serialized JSON: {"age":30,"is_student":false,"languages":["C++","Python","JavaScript"],"name":"Alice"}

反序列化(JSON -> C++ 對象

反序列化是將 JSON 字符串解析為 Json::Value 對象,以便在 C++ 中訪問其內容。我們可以使用 Json::ReaderJson::CharReader 來解析 JSON 字符串。

#include <iostream>
#include <json/json.h>int main() {// 假設我們有一個 JSON 字符串std::string jsonString = "{\"name\":\"Alice\",\"age\":30,\"is_student\":false,\"languages\":[\"C++\",\"Python\",\"JavaScript\"]}";// 創建一個 Json::Value 對象Json::Value root;Json::CharReaderBuilder readerBuilder;std::string errs;// 使用 CharReader 解析 JSON 字符串std::istringstream iss(jsonString);if (!parseFromStream(readerBuilder, iss, &root, &errs)) {std::cerr << "Failed to parse JSON: " << errs << std::endl;return -1;}// 訪問 JSON 數據std::string name = root["name"].asString();int age = root["age"].asInt();bool isStudent = root["is_student"].asBool();// 獲取數組Json::Value languages = root["languages"];std::cout << "Deserialized JSON:" << std::endl;std::cout << "Name: " << name << std::endl;std::cout << "Age: " << age << std::endl;std::cout << "Is Student: " << (isStudent ? "Yes" : "No") << std::endl;std::cout << "Languages: ";for (unsigned int i = 0; i < languages.size(); ++i) {std::cout << languages[i].asString() << " ";}std::cout << std::endl;return 0;
}

反序列化結果:

Deserialized JSON:
Name: Alice
Age: 30
Is Student: No
Languages: C++ Python JavaScript 

5. 總結

  • 序列化 :通過 Json::Value 構建 JSON 對象,并使用 Json::FastWriterJson::StreamWriter 將其轉換為 JSON 字符串。
  • 反序列化 :通過 Json::ReaderJson::CharReader 將 JSON 字符串解析為 Json::Value 對象,然后可以通過 asString()asInt() 等方法訪問數據。

JsonCpp 是一個非常方便的庫,適合在 C++ 項目中處理 JSON 數據。

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

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

相關文章

Ubuntu——執行echo $USE什么都不顯示

問題&#xff1a;“執行 echo $USER 什么都不顯示”&#xff1f; 一、原因分析 環境變量 $USER 未正確設置 $USER 是系統自動定義的環境變量&#xff0c;通常用于表示當前登錄的用戶名。若該變量未設置或為空&#xff0c;執行 echo $USER 會無輸出。可能場景&#xff1a; 用戶通…

uni-app學習筆記五--vue3插值表達式的使用

vue3快速上手導航&#xff1a;簡介 | Vue.js 模板語法 插值表達式 最基本的數據綁定形式是文本插值&#xff0c;它使用的是“Mustache”語法 (即雙大括號)&#xff1a; <span>Message: {{ msg }}</span> 雙大括號標簽會被替換為相應組件實例中 msg 屬性的值。同…

【PSINS工具箱】基于工具箱的單獨GNSS導航、單獨INS導航、兩者結合組合導航,三種導航的對比程序。附完整的代碼

本文給出基于PSINS工具箱的單獨GNSS導航、單獨INS導航、兩者結合組合導航(153EKF)的程序。并提供三者的軌跡對比、誤差對比。 文章目錄 運行結果MATLAB代碼代碼的簡單介紹簡介2. 平均絕對誤差 (MAE)主要模塊運行結果 三軸軌跡圖: 各軸誤差曲線: 命令行窗口的結果輸出: …

C. scanf 函數基礎

scanf 函數 1. scanf 函數基礎1.1 函數原型與頭文件1.2 格式化輸入的基本概念2.1 常見格式說明符整數格式說明符浮點數格式說明符字符和字符串格式說明符其他格式說明符2.2 格式說明符的高級用法寬度修飾符精度修飾符跳過輸入字段寬度組合修飾符對齊修飾符實際應用示例3.2 精度…

spring cloud loadbalancer實現機房感知的負載均衡

1 概述 在同城多機房情景下&#xff0c;各個機房各自部署一套微服務集群&#xff0c;正常情況下微服務調用在本機房閉環。在如下某些災難情景&#xff0c;可以嘗試拉遠調用以最大程度維持業務連續性&#xff0c;這些情景例如&#xff1a; A機房多個服務器宕機。應用由于BUG發…

vue中,created和mounted兩個鉤子之間調用時差值受什么影響

在 Vue 中&#xff0c;created 和 mounted 是兩個生命周期鉤子&#xff0c;它們之間的調用時差主要受以下幾個因素影響&#xff1a; &#x1f7e2; 1. 模板復雜度與渲染耗時&#xff08;最主要因素&#xff09; mounted 的觸發時間是在組件的 DOM 被掛載之后&#xff08;也就是…

Linux篇 第2章Linux基礎指令

Linux篇 第2章Linux基礎指令 文章目錄 前言一、基礎的一些命令1.pwd2.mkdir3.ls4.cd5.clear 二、ls1.ls -l2.ls -a3.ls -l -a 三、touch四、 cd1.cd /2.cd ..3.cd ~4. cd - 五、tree1. Linux系統文件的結構2.絕對路徑和相對路徑 六、mkdir -p七、rmdir&#xff08;沒啥用&#…

Scrapyd 詳解:分布式爬蟲部署與管理利器

Scrapyd 是 Scrapy 官方提供的爬蟲部署與管理平臺&#xff0c;支持分布式爬蟲部署、定時任務調度、遠程管理爬蟲等功能。本文將深入講解 Scrapyd 的核心功能、安裝配置、爬蟲部署流程、API 接口使用&#xff0c;以及如何結合 Scrapy-Redis 實現分布式爬蟲管理。通過本文&#x…

國產免費工作流引擎star 6.5k,Warm-Flow升級1.7.2(新增案例和修復缺陷)

文章目錄 主要更新內容項目介紹功能思維導圖設計器流程圖演示地址官網Warm-Flow視頻 主要更新內容 [feat] 開啟流程實例&#xff0c;新增流程定義是否存在校驗[feat] 新增合同簽訂流程案例[feat] 新增企業采購流程案例[update] mybatis-plus邏輯刪除&#xff0c;刪除值和未刪除…

數據倉庫Hive

1.數據倉庫 1.1數據倉庫的概念 數據倉庫&#xff08;Data Warehouse&#xff09;是一個面向主題的、集成的、相對穩定的、反映歷史變化的數據集合&#xff0c;用于支持管理決策。 面向主題。操作型數據庫的數據組織面向事務處理任務&#xff0c;而數據倉庫中的數據按照一定的…

dify 連接不上ollama An error occurred during credentials validation:

三大報錯 An error occurred during credentials validation: HTTPConnectionPool(hosthost.docker.internal, port11434): Max retries exceeded with url: /api/chat (Caused by NameResolutionError("<urllib3.connection.HTTPConnection object at 0x7f26fc3c00b0&…

uniapp 生成海報二維碼 (微信小程序)

先下載qrcodenpm install qrcode 調用 community_poster.vue <template><view class"poster-page"><uv-navbar title"物業推廣碼" placeholder autoBack></uv-navbar><view class"community-info"><text clas…

如何理解編程中的遞歸、迭代與回歸?

作為編程初學者&#xff0c;遞歸、迭代和回歸這三個概念常常讓人感到困惑。本文將通過生活化的比喻、Python代碼示例和直觀的對比&#xff0c;幫助你徹底理解這三個重要概念及其應用場景。 一、從生活比喻理解核心概念 1. 遞歸&#xff08;Recursion&#xff09;—— 俄羅斯套…

Android Studio 模擬器配置方案

Android Studio 模擬器配置方案 1.引言2.使用Android Studio中的模擬器3.使用國產模擬器1.引言 前面介紹【React Native基礎環境配置】的時候需要配置模擬器,當時直接使用了USB調試方案,但是有些時候可能不太方便連接手機調試,比如沒有iPhone調不了ios。接下來說明另外兩種可…

uniapp(vue3)動態計算swiper高度封裝自定義hook

// useCalculateSwiperHeight.ts import { ref, onMounted } from vue;export function useCalculateSwiperHeight(headerSelector: string .header-search, tabsWrapperSelector: string .u-tabs .u-tabs__wrapper) {const swiperHeight ref<number>(0);// 封裝uni.g…

從代碼學習深度學習 - 轉置卷積 PyTorch版

文章目錄 前言基本操作填充、步幅和多通道填充 (Padding)步幅 (Stride)多通道總結前言 在卷積神經網絡(CNN)的大家族中,我們熟悉的卷積層和匯聚(池化)層通常會降低輸入特征圖的空間維度(高度和寬度)。然而,在許多應用場景中,例如圖像的語義分割(需要對每個像素進行分…

c語言第一個小游戲:貪吃蛇小游戲06

實現貪吃蛇四方向的風騷走位 實現代碼 #include <curses.h> #include <stdlib.h> struct snake{ int hang; int lie; struct snake *next; }; struct snake *head; struct snake *tail; int key; int dir; //全局變量 #define UP 1 //這個是宏定義&a…

django的權限角色管理(RBAC)

在 Django 中&#xff0c;User、Group 和 Permission 是權限系統的核心組件。下面通過代碼示例演示它們的 CRUD&#xff08;創建、讀取、更新、刪除&#xff09; 操作&#xff1a; 一、User 模型 CRUD from django.contrib.auth.models import User# 創建用戶 user User.obje…

解決docker alpine缺少字體的問題 Could not initialize class sun.awt.X11FontManager

制作的springboot項目鏡像&#xff0c;缺少字體報錯Could not initialize class sun.awt.X11FontManager 原因鏡像中缺少字體 解決&#xff1a; 制作鏡像時&#xff0c;添加字體庫&#xff0c;Dockerfile文件 中添加如下內容 注意&#xff1a; jdk版本一定要使用&#xff0…

MQTT 在Spring Boot 中的使用

在 Spring Boot 中使用 MQTT 通常會借助 Spring Integration 項目提供的 MQTT 支持。這使得 MQTT 的集成可以很好地融入 Spring 的消息驅動和企業集成模式。 以下是如何在 Spring Boot 中集成和使用 MQTT 的詳細步驟&#xff1a; 前提條件&#xff1a; MQTT Broker&#xff…