Zeke Xiao

Zeke Xiao

github

使用 nlohmann/json 序列化

nlohmann/json 现代 C++ 的 JSON 库

#include <iostream>
#include <fstream>
#include <vector>
#include <optional>

#include "json.hpp"

namespace nl = nlohmann;

enum class TestEnum : int {
    左 = 0,

};

struct SubTestStruct {
    int 测试 = 0;
};

struct TestStruct {
    int 测试 = 0;
    bool 测试Bool = false;
    TestEnum 测试Enum = TestEnum::左;
    std::optional<bool> 测试Opt;
    std::vector<int> 测试Vec;
    SubTestStruct 子测试结构体;
};

// nl 不直接支持 optional, 使用 adl_serializer 可以支持任意类型的序列化
// https://github.com/nlohmann/json/pull/2117
// https://github.com/nlohmann/json#how-do-i-convert-third-party-types
namespace nlohmann {
    template <typename T>
    struct adl_serializer<std::optional<T>> {
        static void to_json(json& j, const std::optional<T>& opt) {
            if (opt == std::nullopt) {
                j = nullptr;
            } else {
              j = *opt; // this will call adl_serializer<T>::to_json which will
                        // find the free function to_json in T's namespace!
            }
        }

        static void from_json(const json& j, std::optional<T>& opt) {
            if (j.is_null()) {
                opt = std::nullopt;
            } else {
                opt = j.get<T>(); // same as above, but with
                                  // adl_serializer<T>::from_json
            }
        }
    };
}

// 序列化struct,class
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SubTestStruct, 测试)
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(TestStruct, 测试, 测试Bool, 测试Enum, 测试Opt, 测试Vec, 子测试结构体)

// 序列化enum
NLOHMANN_JSON_SERIALIZE_ENUM(TestEnum, {
    {TestEnum::左, "左"},
    {TestEnum::右, "右"},
})

void 打印测试(const TestStruct& s) {
    nl::json jsonValue;
    nl::to_json(jsonValue, s);

    std::cout << "TestStruct 测试: " << s.测试
              << ", 测试Bool: " << s.测试Bool
              << ", 测试Enum: " << (int) s.测试Enum
              << ", 测试Opt: " << (s.测试Opt.has_value() && s.测试Opt.value())
              << ", 测试Vec: { ";
    for(auto val : s.测试Vec) {
        std::cout << val << ",";
    }
    std::cout << "\b" << " }";
    std::cout << ", 子测试结构体.测试: " << s.子测试结构体.测试;
    std::cout << std::endl;
}

int main() {
    // 写入
    std::ofstream sf("config.json");
    nl::json j;
    TestStruct s;
    s.测试 = 100;
    s.测试Opt = true;
    for(int i = 0; i < 5; ++i) {
        s.测试Vec.push_back(i);
    }
    s.子测试结构体.测试 = 99;
    打印测试(s);
    nl::to_json(j, s);
    // 单独获取一个值
    std::cout << "Json value: " << j["测试"] << std::endl;
    //  写入文件
    sf << j;
    sf.close();

    //  读取
    std::ifstream  is("config.json");
    nl::json readJson;
    is >> readJson;
    TestStruct newS = readJson.get<TestStruct>();
//    nl::from_json(readJson, newS);
    打印测试(newS);
    is.close();
    return 0;
}

注: nl_json 是一个 utf-8 only 库,中文下使用需要注意编码

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。