JsonCpp JSON格式處理庫的介紹和使用(面向業務程式設計-檔案格式處理)

2023-04-05 06:01:11

JsonCpp JSON格式處理庫的介紹和使用(面向業務程式設計-檔案格式處理)

介紹

JSON是一種輕量級的資料交換格式,它是一種鍵值對的集合。它的值可以是數位、字串、布林值、序列。

想知道更多有關JSON格式的介紹,可以到JSON的官網json.org學習

JsonCpp是一個c++庫,允許對JSON值進行操作,包括對字串的序列化和反序列化。它還可以在反序列化/序列化步驟中儲存現有註釋,使其成為儲存使用者輸入檔案的方便格式。

Github地址:jsoncpp

使用範例

JsonCpp相對於其他的JSON解析庫,它的好處就是非常的容易使用

因為它有一個非常好的特性:下標存取(包括array型別)

    const std::string name = root["Name"].asString();
    const int age = root["Age"].asInt();

上述程式碼中,Name欄位在JSON中是一個String型別,然後通過解析後的root(Json::Value物件)的下標存取

實際上通過重寫下標操作符[]實現

讀取解析讀取string

讀取一個JSON格式的string,程式碼如下

#include "json/json.h"
#include <iostream>
#include <memory>

int readJsonExample() {
    const std::string rawJson = R"({"Age": 20, "Name": "colin"})";
    const auto rawJsonLength = static_cast<int>(rawJson.length());
    constexpr bool shouldUseOldWay = false;
    JSONCPP_STRING err;
    Json::Value root;

    if (shouldUseOldWay) {
        Json::Reader reader;
        reader.parse(rawJson, root);
    } else {
        Json::CharReaderBuilder builder;
        const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
        if (!reader->parse(rawJson.c_str(), rawJson.c_str() + rawJsonLength, &root,
                           &err)) {
            std::cout << "error" << std::endl;
            return EXIT_FAILURE;
        }
    }
    const std::string name = root["Name"].asString();
    const int age = root["Age"].asInt();

    std::cout << name << std::endl;
    std::cout << age << std::endl;
    return EXIT_SUCCESS;
}
int main() {
    return readJsonExample();
}

可以看到上面沒有使用oldway去解析,新的方法採用CharReaderBuilder生成Reader,其實新的解析寫法和之前沒有很大的不一樣

輸出

colin
20

從原始資料構建JSON並序列化

#include "json/json.h"
#include <iostream>

int writeJsonString() {
    Json::Value root;
    Json::Value data;
    constexpr bool shouldUseOldWay = false;
    root["action"] = "run";
    data["number"] = 1;
    root["data"] = data;

    if (shouldUseOldWay) {
        Json::FastWriter writer;
        const std::string json_file = writer.write(root);
        std::cout << json_file << std::endl;
    } else {
        Json::StreamWriterBuilder builder;
        const std::string json_file = Json::writeString(builder, root);
        std::cout << json_file << std::endl;
    }
    return EXIT_SUCCESS;
}
int main() {
    return writeJsonString();
}

可以看到差不多,其實可以直接理解為存取物件的下標,然後把實際的數值放進去,JsonCpp會自動判斷等號右邊的型別。很直觀,也比較容易理解

輸出

{
        "action" : "run",
        "data" :
        {
                "number" : 1
        }
}

以庫的形式新增到專案中

本文為作者原創文章,參照請註明出處:https://www.cnblogs.com/nbtech/p/use_jsoncpp_library.html

mkdir UseJsonCppProject && cd UseJsonCppProject
git clone https://github.com/open-source-parsers/jsoncpp.git
vim CMakeLists.txt

CMakeLists.txt內容如下

cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(jsoncpp-test LANGUAGES CXX)

# jsoncpp
include_directories(jsoncpp/include)
add_subdirectory(jsoncpp lib)

# executable output
add_executable(jt main.cpp)
target_link_libraries(jt jsoncpp_lib)

這裡解釋一下前面兩行宣告專案,include_directories是包含jsoncpp的標頭檔案,add_subdirectory是新增jsoncpp工程本身的CMakeLists.txt到當前目錄下,最後兩行是新增可執行檔案還有將jsoncpp庫連結到可執行檔案

add_executable需要加到add_subdirectory的下面

main.cpp檔案可以使用上面的範例

寫完之後建立目錄並編譯

# https://www.cnblogs.com/nbtech/p/use_jsoncpp_library.html
mkdir build && cd build
cmake .. && make

在我們專案中,用CMake新增jsoncpp庫操作如上

交叉編譯?

有時候我們希望它可以跨平臺,那麼只需要在cmake設定的時候指定交叉編譯工具即可

cmake -D CMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++ ..