最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++使用nlohmann/json庫解析和處理JSON數(shù)據(jù)的操作指南

 更新時間:2025年10月29日 08:47:00   作者:光頭閃亮亮  
本章節(jié)介紹了如何在C++項目中使用nlohmann/json庫來解析和處理JSON數(shù)據(jù),我們將展示如何安裝和配置該庫,并通過封裝的JsonHandler類來簡化JSON數(shù)據(jù)的操作過程,需要的朋友可以參考下

1. nlohmann/json庫介紹

nlohmann/json 是一個用于現(xiàn)代C++的JSON庫,由Niels Lohmann開發(fā)。它是一個單頭文件庫,使用C++11標準編寫,具有以下特點:

  • 簡潔的API:語法直觀,像訪問原生C++數(shù)據(jù)結(jié)構(gòu)一樣操作JSON
  • 類型安全:提供了類型檢查和異常處理機制
  • 高性能:比許多其他JSON庫更快
  • 零依賴:只需要包含一個頭文件即可使用
  • 跨平臺:支持Windows、Linux、macOS等操作系統(tǒng)

1.1 下載安裝

nlohmann/json庫可以通過多種方式獲取和安裝:

通過包管理器安裝

  • vcpkg: vcpkg install nlohmann-json
  • Conan: conan install nlohmann_json/3.11.2
  • apt (Ubuntu/Debian): sudo apt install nlohmann-json3-dev

手動下載

1.2 配置方法

在項目中使用nlohmann庫非常簡單:

包含頭文件

#include <nlohmann/json.hpp>
// 或者使用別名
using json = nlohmann::json;

CMake配置(如果通過包管理器安裝):

find_package(nlohmann_json CONFIG REQUIRED)
target_link_libraries(main PRIVATE nlohmann_json::nlohmann_json)

手動配置

  • json.hpp文件放在項目目錄中
  • 在代碼中包含:#include "nlohmann/json.hpp"

在本項目中,我們直接將json.hpp文件包含在項目中,無需額外配置。

2. 應(yīng)用場景

在本項目中,nlohmann庫主要應(yīng)用于以下場景:

2.1 解析HTTP響應(yīng)中的JSON數(shù)據(jù)

當(dāng)客戶端向服務(wù)器發(fā)送GET或POST請求后,服務(wù)器返回的數(shù)據(jù)通常是JSON格式。我們需要使用nlohmann/json庫來解析這些數(shù)據(jù),提取有用信息。

2.2 格式化JSON數(shù)據(jù)用于展示

為了在WebView中更好地展示JSON數(shù)據(jù),我們需要將其格式化為帶有語法高亮的HTML格式。

2.3 構(gòu)造JSON請求數(shù)據(jù)

在向服務(wù)器發(fā)送POST請求時,我們需要構(gòu)造JSON格式的請求體數(shù)據(jù)。

2.4 處理文件列表等結(jié)構(gòu)化數(shù)據(jù)

服務(wù)器返回的文件列表等信息通常以JSON數(shù)組形式提供,需要使用nlohmann庫進行解析和處理。

3. 使用JsonHandler封裝nlohmann/json庫相關(guān)方法

為了更好地管理和重用JSON處理代碼,我們創(chuàng)建了JsonHandler類來封裝所有與nlohmann/json庫相關(guān)的操作。

3.1 JsonHandler.h頭文件

#ifndef JSONHANDLER_H
#define JSONHANDLER_H

#include <wx/string.h>
#include <nlohmann/json.hpp>
using json = nlohmann::json;

class JsonHandler {
    public:
    JsonHandler();
    ~JsonHandler();

    // JSON處理相關(guān)方法
    void ParseJsonResponse(const std::string& response);
    wxString FormatJsonForHtml(const wxString& jsonStr, const bool& formatBit);
    wxString FormatJsonValue(const json& j);
    wxString FormatJsonValueFormat(const json& j, int indentLevel);
    wxString GenerateJsonHtml(const wxString& jsonResponse, const bool& formatBit);

    // 保存原始JSON數(shù)據(jù)
    void SetRawJsonData(const wxString& rawData) { m_rawJsonData = rawData; }
    wxString GetRawJsonData() const { return m_rawJsonData; }

    private:
    wxString m_rawJsonData;  // 保存原始JSON數(shù)據(jù)
    };

#endif // JSONHANDLER_H

3.2 JsonHandler.cpp實現(xiàn)文件

JsonHandler.cpp文件中實現(xiàn)了所有JSON處理方法:

  1. ParseJsonResponse:解析JSON響應(yīng)數(shù)據(jù)
  2. FormatJsonForHtml:將JSON格式化為HTML顯示格式
  3. FormatJsonValue:遞歸生成不帶縮進的JSON HTML字符串
  4. FormatJsonValueFormat:遞歸生成帶縮進的JSON HTML字符串
  5. GenerateJsonHtml:生成完整的JSON顯示HTML頁面

下面是這些方法的具體實現(xiàn):

3.2.1 ParseJsonResponse方法實現(xiàn)

// 解析 JSON 響應(yīng)
void JsonHandler::ParseJsonResponse(const std::string& response) {
    // 嘗試解析 JSON
    try {
        // 使用nlohmann庫解析JSON字符串
        json j = json::parse(response);
        // 將 JSON 格式化為帶縮進的字符串
        std::string json_str = j.dump(4);
        // 記錄日志
        wxLogInfo(wxString::FromUTF8("JSON: %s"), wxString::FromUTF8(json_str.c_str()));
        // 檢查是否存在 "message" 字段
        if (j.contains("message")) {
            // 獲取message字段的值
            std::string message = j["message"];
            // 記錄解析結(jié)果到日志
            wxLogInfo(wxString::FromUTF8("解析結(jié)果: %s"), wxString::FromUTF8(message.c_str()));
        } else {
            // 如果缺少message字段,記錄錯誤日志
            wxLogInfo(wxString::FromUTF8("JSON格式錯誤: 缺少message字段"));
        }

        // 檢查是否存在 "data" 數(shù)組
        if (j.contains("data") && j["data"].is_array()) {
            // 獲取data數(shù)組
            json dataArray = j["data"];
            // 遍歷數(shù)組中的每個元素
            for (const auto& item : dataArray) {
                // 檢查元素是否包含name和age字段且類型正確
                if (item.contains("name") && item["name"].is_string() && item.contains("age") && item["age"].is_number()) {
                    // 提取name和age字段的值
                    std::string name = item["name"];
                    int age = item["age"];
                    // 在日志中顯示name和age信息
                    wxLogMessage(wxString::FromUTF8("Name: %s, Age: %d"), wxString::FromUTF8(name.c_str()), age);
                }
            }
        } else {
            // 如果缺少data數(shù)組或格式不正確,記錄錯誤日志
            wxLogInfo(wxString::FromUTF8("JSON格式錯誤: 缺少data數(shù)組或格式不正確"));
        }
    } catch (const json::parse_error& e) {
        // JSON 解析失敗
        std::string parseErrorMsg = "JSON解析失敗: " + std::string(e.what());
        wxLogError(wxString::FromUTF8(parseErrorMsg.c_str()));
    }
}

3.2.2 FormatJsonForHtml方法實現(xiàn)

// 格式化JSON字符串用于HTML顯示
wxString JsonHandler::FormatJsonForHtml(const wxString& jsonStr, const bool& formatBit) {
    try {
        // 確保使用UTF-8編碼
        std::string utf8Json = std::string(jsonStr.ToUTF8());
        // 使用nlohmann庫解析JSON字符串
        json j = json::parse(utf8Json);
        wxLogError("***************************************************");
        wxLogError(j.dump());
        wxLogError("***************************************************");

        // 遞歸生成帶有HTML類名的JSON字符串
        wxString formattedJson;
        if (!formatBit) {
            // 使用不帶縮進的方式格式化JSON
            formattedJson = FormatJsonValue(j);
        } else {
            // 使用帶縮進的方式格式化JSON
            formattedJson = FormatJsonValueFormat(j, 0);
        }
        wxLogError(wxT("格式化JSON字符串成功!"));
        // 返回格式化后的JSON字符串
        return formattedJson;
    } catch (const json::parse_error& e) {
        // 記錄JSON解析錯誤日志
        wxLogError("JSON Parse Err: %s", e.what());
        wxLogError(wxT("格式化JSON字符串失?。?));
        // 返回原始JSON字符串
        return jsonStr;
    }
}

3.2.3 FormatJsonValue方法實現(xiàn)

// 遞歸生成帶有HTML類名的JSON字符串(不帶格式化)
wxString JsonHandler::FormatJsonValue(const json& j) {
    // 判斷JSON值是否為對象類型
    if (j.is_object()) {
        // 如果是 JSON 對象
        wxString result = wxT("{");
        bool first = true;
        // 遍歷對象中的每個鍵值對
        for (auto& [key, value] : j.items()) {
            if (!first) {
                // 如果不是第一個元素,添加逗號分隔符
                result += wxT(",");
            }
            first = false;

            // 添加鍵,使用特定CSS類名進行標記
            result += wxString::Format(wxT("<span class='json-key'>\"%s\"</span>: "), wxString::FromUTF8(key.c_str()));

            // 遞歸處理值
            result += FormatJsonValue(value);
        }
        result += wxT("}");
        wxLogError("----------------------------------------------------------------------");
        wxLogError(result);
        wxLogError("----------------------------------------------------------------------");
        // 返回格式化后的對象字符串
        return result;
    } else if (j.is_array()) {
        // 如果是 JSON 數(shù)組
        wxString result = wxT("[");
        bool first = true;
        // 遍歷數(shù)組中的每個元素
        for (auto& item : j) {
            if (!first) {
                // 如果不是第一個元素,添加逗號分隔符
                result += wxT(",");
            }
            first = false;

            // 遞歸處理數(shù)組項
            result += FormatJsonValue(item);
        }
        result += wxT("]");
        // 返回格式化后的數(shù)組字符串
        return result;
    } else if (j.is_string()) {
        // 如果是 JSON 字符串
        std::string jsonString = j.get<std::string>();

        // 使用 wxString::FromUTF8 正確處理UTF-8編碼的字符串
        wxString wxStringValue = wxString::FromUTF8(jsonString.c_str());
        wxLogMessage("字符串值: %s", wxStringValue);

        // 轉(zhuǎn)義HTML特殊字符以防止在HTML中顯示錯誤
        wxString escapedValue = wxStringValue;
        escapedValue.Replace("&", "&amp;");   // 轉(zhuǎn)義&符號
        escapedValue.Replace("<", "&lt;");    // 轉(zhuǎn)義<符號
        escapedValue.Replace(">", "&gt;");    // 轉(zhuǎn)義>符號
        escapedValue.Replace("\"", "&quot;"); // 轉(zhuǎn)義雙引號
        escapedValue.Replace("'", "&#39;");   // 轉(zhuǎn)義單引號

        // 使用特定CSS類名標記字符串值并返回
        return wxString::Format("<span class='json-string'>\"%s\"</span>", escapedValue);
    } else if (j.is_number_integer() || j.is_number_unsigned()) {
        // 如果是 JSON 數(shù)字(整數(shù))
        // 使用特定CSS類名標記整數(shù)并返回
        return wxString::Format(wxT("<span class='json-number'>%lld</span>"), j.get<int64_t>());
    } else if (j.is_number_float()) {
        // 如果是 JSON 數(shù)字(浮點數(shù))
        // 使用特定CSS類名標記浮點數(shù)并返回
        return wxString::Format(wxT("<span class='json-number'>%.6f</span>"), j.get<double>());
    } else if (j.is_boolean()) {
        // 如果是 JSON 布爾值
        // 根據(jù)布爾值返回true或false,并使用特定CSS類名標記
        return j.get<bool>() ? wxT("<span class='json-boolean'>true</span>") : wxT("<span class='json-boolean'>false</span>");
    } else if (j.is_null()) {
        // 如果是 JSON null
        // 使用特定CSS類名標記null值并返回
        return wxT("<span class='json-null'>null</span>");
    }
    // 對于其他類型,使用特定CSS類名標記并返回
    return wxString::Format("<span class='json-string'>%s</span>", j.dump().c_str());
}

3.2.4 FormatJsonValueFormat方法實現(xiàn)

// 遞歸生成帶有HTML類名的JSON字符串(帶格式化和縮進)
wxString JsonHandler::FormatJsonValueFormat(const json& j, int indentLevel) {
    // 生成當(dāng)前層級的縮進字符串(每級2個空格)
    wxString indent(indentLevel * 2, ' ');
    // 生成內(nèi)層縮進字符串(比當(dāng)前層級多一級)
    wxString indentInner((indentLevel + 1) * 2, ' ');

    // 判斷JSON值是否為對象類型
    if (j.is_object()) {
        // 如果是 JSON 對象
        if (j.empty()) {
            // 如果對象為空,直接返回{}
            return wxT("{}");
        }

        wxString result = wxT("{\n");
        bool first = true;
        // 遍歷對象中的每個鍵值對
        for (auto& [key, value] : j.items()) {
            if (!first) {
                // 如果不是第一個元素,添加逗號和換行符
                result += wxT(",\n");
            }
            first = false;

            // 添加鍵和值,帶縮進
            result += indentInner + wxString::Format(
                wxT("<span class='json-key'>\"%s\"</span>: %s"),
                wxString::FromUTF8(key.c_str()),
                // 遞歸處理值,縮進層級加1
                FormatJsonValueFormat(value, indentLevel + 1)
            );
        }
        // 添加換行符、縮進和結(jié)束括號
        result += wxT("\n") + indent + wxT("}");
        // 返回格式化后的對象字符串
        return result;
    } else if (j.is_array()) {
        // 如果是 JSON 數(shù)組
        if (j.empty()) {
            // 如果數(shù)組為空,直接返回[]
            return wxT("[]");
        }

        wxString result = wxT("[\n");
        bool first = true;
        // 遍歷數(shù)組中的每個元素
        for (auto& item : j) {
            if (!first) {
                // 如果不是第一個元素,添加逗號和換行符
                result += wxT(",\n");
            }
            first = false;

            // 添加數(shù)組項,帶縮進
            result += indentInner + FormatJsonValueFormat(item, indentLevel + 1);
        }
        // 添加換行符、縮進和結(jié)束括號
        result += wxT("\n") + indent + wxT("]");
        // 返回格式化后的數(shù)組字符串
        return result;
    } else if (j.is_string()) {
        // 如果是 JSON 字符串
        std::string jsonString = j.get<std::string>();

        // 使用 wxString::FromUTF8 正確處理UTF-8編碼的字符串
        wxString wxStringValue = wxString::FromUTF8(jsonString.c_str());
        wxLogMessage("字符串值: %s", wxStringValue);

        // 轉(zhuǎn)義HTML特殊字符以防止在HTML中顯示錯誤
        wxString escapedValue = wxStringValue;
        escapedValue.Replace("&", "&amp;");   // 轉(zhuǎn)義&符號
        escapedValue.Replace("<", "&lt;");    // 轉(zhuǎn)義<符號
        escapedValue.Replace(">", "&gt;");    // 轉(zhuǎn)義>符號
        escapedValue.Replace("\"", "&quot;"); // 轉(zhuǎn)義雙引號
        escapedValue.Replace("'", "&#39;");   // 轉(zhuǎn)義單引號

        // 使用特定CSS類名標記字符串值并返回
        return wxString::Format("<span class='json-string'>\"%s\"</span>", escapedValue);
    } else if (j.is_number_integer() || j.is_number_unsigned()) {
        // 如果是 JSON 數(shù)字(整數(shù))
        // 使用特定CSS類名標記整數(shù)并返回
        return wxString::Format(wxT("<span class='json-number'>%lld</span>"), j.get<int64_t>());
    } else if (j.is_number_float()) {
        // 如果是 JSON 數(shù)字(浮點數(shù))
        // 使用特定CSS類名標記浮點數(shù)并返回
        return wxString::Format(wxT("<span class='json-number'>%.6f</span>"), j.get<double>());
    } else if (j.is_boolean()) {
        // 如果是 JSON 布爾值
        // 根據(jù)布爾值返回true或false,并使用特定CSS類名標記
        return j.get<bool>() ? wxT("<span class='json-boolean'>true</span>") : wxT("<span class='json-boolean'>false</span>");
    } else if (j.is_null()) {
        // 如果是 JSON null
        // 使用特定CSS類名標記null值并返回
        return wxT("<span class='json-null'>null</span>");
    }

    // 對于其他類型,使用特定CSS類名標記并返回
    return wxString::Format("<span class='json-string'>%s</span>", j.dump().c_str());
}

3.2.5 GenerateJsonHtml方法實現(xiàn)

// 生成 HTML 頁面
wxString JsonHandler::GenerateJsonHtml(const wxString& jsonResponse, const bool& formatBit) {
    wxLogError("jsonResponse:---------------------------------------");
    wxLogError(jsonResponse);
    wxLogError("jsonResponse:---------------------------------------");
    // 格式化JSON數(shù)據(jù)
    wxString formattedJson = FormatJsonForHtml(jsonResponse, formatBit);

    // 構(gòu)造完整的 HTML 字符串
    wxString html = wxString::Format(
        R"(<!DOCTYPE html>
<html>
<head>
    <meta charset='UTF-8'>
    <title>JSON響應(yīng)</title>
    <style>
        body { 
            font-family: 'Segoe UI', Arial, sans-serif; 
            background-color: #f5f5f5; 
            margin: 0; 
            padding: 20px; 
        }
        .json-container { 
            background-color: white; 
            border-radius: 8px; 
            box-shadow: 0 2px 10px rgba(0,0,0,0.1); 
            padding: 20px; 
            overflow-x: auto; 
        }
        h1 { 
            color: #333; 
            border-bottom: 1px solid #eee; 
            padding-bottom: 10px; 
            margin-top: 0; 
        }
        pre { 
            font-family: 'Consolas', 'Courier New', monospace;
            font-size: 14px;
            line-height: 1.4;
            margin: 0;
            white-space: pre-wrap; /* 保留空格和換行 */
        }
        .json-key { color: #e74c3c; font-weight: bold; }
        .json-string { color: #27ae60; }
        .json-number { color: #3498db; font-weight: bold; }
        .json-boolean { color: #9b59b6; font-weight: bold; }
        .json-null { color: #95a5a6; font-weight: bold; }
        .toggle { cursor: pointer; }
    </style>
    <script src="./static/highlight.min.js"></script>
    <link rel="stylesheet" href="./static/default.min.css" rel="external nofollow" >
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            hljs.highlightAll();
            const toggles = document.querySelectorAll('.toggle');
            toggles.forEach(toggle => {
                toggle.addEventListener('click', function() {
                    const content = this.nextElementSibling;
                    if (content.style.display === 'none') {
                        content.style.display = 'block';
                    } else {
                        content.style.display = 'none';
                    }
                });
            });
        });
    </script>
</head>
<body>
    <h1>服務(wù)器響應(yīng)</h1>
    <div class='json-container'><pre>%s</pre></div>
</body>
</html>)",
        formattedJson
    );

    // 日志輸出,用于調(diào)試
    wxLogInfo(wxString::FromUTF8("生成的完整HTML:\n%s"), html);

    // 返回生成的HTML頁面
    return html;
}

4. MyFrame.cpp調(diào)用JsonHandler中封裝的各個方法示例

在主框架類MyFrame中,我們通過jsonHandler實例調(diào)用JsonHandler類中封裝的方法。

4.1 示例1:處理GET請求返回的JSON數(shù)據(jù)

// 獲取文件列表的事件處理函數(shù)
void MyFrame::OnGetFileLists(wxCommandEvent& event) {
    // 發(fā)送GET請求獲取文件列表
    std::string url = "/files";
    std::string response = httpClient.HttpGet(url);
    
    // 檢查響應(yīng)是否為空
    if (response.empty()) {
        // 如果返回的響應(yīng)為空,可能是請求失敗
        wxLogError("GET request failed or returned empty response.");
        m_textCtrl->SetValue("GET Request Failed: Empty response.");
        return;
        }
        
    // 保存原始JSON數(shù)據(jù)供后續(xù)使用
    jsonHandler.SetRawJsonData(wxString::FromUTF8(response.c_str()));
    
    // 在瀏覽器控件中顯示格式化的JSON數(shù)據(jù)
    wxString html = jsonHandler.GenerateJsonHtml(wxString::FromUTF8(response.c_str()), false);
    m_webView->SetPage(html, "UTF-8");
    
    // 解析JSON數(shù)據(jù)并填充下拉框
    try {
        // 使用nlohmann庫解析JSON字符串
        json j = json::parse(response);
        
        // 清空下拉框中的現(xiàn)有內(nèi)容
        m_comboBox->Clear();

        // 檢查是否存在 "data" 對象以及 "data.filelist" 數(shù)組
        if (j.contains("data") && j["data"].is_object()) {
            // 獲取data對象
            json dataObj = j["data"];

            // 檢查是否存在 "filelist" 數(shù)組
            if (dataObj.contains("filelist") && dataObj["filelist"].is_array()) {
                // 獲取文件列表數(shù)組
                json fileArray = dataObj["filelist"];
                // 遍歷數(shù)組中的每個文件項
                for (const auto& item : fileArray) {
                    // 檢查項是否包含name字段且為字符串類型
                    if (item.contains("name") && item["name"].is_string()) {
                        // 提取文件名
                        std::string name = item["name"];
                        // 將文件名添加到下拉框中
                        m_comboBox->Append(wxString::FromUTF8(name.c_str()));
                        }
                    }
                }
            }
        }
    // 捕獲JSON解析錯誤
    catch (const json::parse_error& e) {
        // JSON 解析失敗
        std::string parseErrorMsg = "JSON解析失敗: " + std::string(e.what());
        wxLogError(wxString::FromUTF8(parseErrorMsg.c_str()));
        }
    }

4.2 示例2:格式化顯示JSON數(shù)據(jù)

// 格式化JSON顯示的事件處理函數(shù)
void MyFrame::OnFormatJson(wxCommandEvent& event) {
    // 使用格式化方式生成JSON HTML頁面
    wxString html = jsonHandler.GenerateJsonHtml(jsonHandler.GetRawJsonData(), true);
    
    // 清除WebView的歷史記錄
    m_webView->ClearHistory();
    // 重新加載頁面
    m_webView->Reload();
    // 在WebView中顯示格式化的JSON數(shù)據(jù)
    m_webView->SetPage(html, "UTF-8");
    }

5. 總結(jié)

通過使用nlohmann/json庫和封裝的JsonHandler類,我們能夠:

  1. 簡化JSON數(shù)據(jù)的解析和處理過程
  2. 提供格式化的JSON數(shù)據(jù)顯示功能
  3. 實現(xiàn)JSON數(shù)據(jù)的保存和重用
  4. 保證代碼的模塊化和可維護性

nlohmann/json庫的使用大大簡化了C++中JSON數(shù)據(jù)的處理,其直觀的API設(shè)計使得JSON操作就像訪問原生數(shù)據(jù)結(jié)構(gòu)一樣簡單。通過封裝在JsonHandler類中,我們實現(xiàn)了代碼的重用和更好的維護性。

以上就是C++使用nlohmann/json庫解析和處理JSON數(shù)據(jù)的操作指南的詳細內(nèi)容,更多關(guān)于C++ nlohmann/json解析和處理JSON的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論

德安县| 修文县| 江陵县| 泊头市| 清流县| 屯门区| 温泉县| 淅川县| 济宁市| 常宁市| 诸城市| 芒康县| 余庆县| 游戏| 盐池县| 永登县| 上林县| 宜宾县| 濮阳市| 白城市| 蕲春县| 军事| 泸水县| 馆陶县| 搜索| 卓尼县| 仙游县| 沙湾县| 巴楚县| 方山县| 丰顺县| 通道| 鹿泉市| 潢川县| 三亚市| 西昌市| 曲水县| 清涧县| 五华县| 怀宁县| 马山县|