zoukankan      html  css  js  c++  java
  • Json常用格式

    常用的json序列化工具有jsoncpp,nlohmann.(nlohmann的使用一定要捕捉异常)

    解析一些常用的json格式,上述工具的使用方式分别是什么。

    备注:分割线的前者是nlohmann的使用,后者是jsoncpp的使用

    序列化

    nlohmann::json j="XXXXXX";
    std::string str = j.dump(4); //带换行缩进,参数是缩进空格数
    

    Json::Value value = "XXXXXX";
    std::string str = value.toStyledString();
    

    反序列化

    std::string str = "XXXXXX";
    nlohmann::json j = nlohmann::json::parse(str);
    

    std::string str = "XXXXXX";
    Json::Value value;
    Json::Reader reader;
    if (reader.parse(str, value)) {
    }
    

    磁盘存取

    读取

    std::ifstream in("E:\XXXX.json");
    json j;
    in >> j;            //json数据:j
    in.close();
    std::string content = j.dump(4);    //string数据:content
    

    std::ifstream in("E:\XXXX.json");
    Json::Value value;
    Json::Reader reader;
    if (reader.parse(in, value)) {      
        //json数据:value  ;string数据:content
        std::string content = value.toStyledString();      
    }
    in.close();
    

    写入

    nlohmann::json j="XXXXXX";
    std::ofstream out("E:\XXXX.json");
    out<<j.dump(4);
    out.close();
    

    Json::Value value="XXXXXX";
    std::ofstream out("E:\XXXX.json");
    out<<value.toStyledString();
    out.close();
    

    判断字段是否存在,并且获取对应的字段

    类型主要有:null,bool,object,array,string,number.

    方式一:
    std::ifstream in("E:\XXXX.json");
    try {
        nlohmann::json j = nlohmann::json::parse(in);
        if (j.contains("password") && j["password"].is_string()) {
            std::string str = j["password"].get<std::string>();
        }
    } catch (const std::exception& ex) {
    }
    in.close();
    
    方式二:
     auto iter = j.find("deviceId");
     if (iter != j.end()) {
         std::string str = j["deviceId"].get<std::string>();
    }
    

    std::ifstream in("E:\XXXX.json");
    Json::Value value;
    Json::Reader reader;
    if (reader.parse(in, value)) {
        if (value.isMember("password") && value["password"].isString()) {
            std::string str = value["password"].asString();
        }
    }
    in.close();
    

    数组的序列化与反序列化

    e.g.
    [
    	"test1",
    	"test2",
    	"test3"
    ]
    

    普通数组序列化到Json数组

    std::vector<std::string> vet;
    vet.emplace_back("test1");
    vet.emplace_back("test2");
    vet.emplace_back("test3");
    
    nlohmann::json j;
    for (auto &iter : vet) {
        j.push_back(iter);
    }
    
    std::ofstream out("E:\XXXX.json");
    out << j.dump(4);
    out.close();
    

    std::vector<std::string> vet;
    vet.emplace_back("test1");
    vet.emplace_back("test2");
    vet.emplace_back("test3");
    
    Json::Value value;
    for (unsigned i = 0; i < vet.size(); ++i) {
        value[i] = vet[i];
    }
    
    std::ofstream out("E:\XXXX.json");
    out << value.toStyledString();
    out.close();
    

    nlohmann对于数组操作,有更为简便的优势:

    std::vector<std::string> vet;
    vet.emplace_back("test1");
    vet.emplace_back("test2");
    vet.emplace_back("test3");
    
    nlohmann::json j(vet);
    std::ofstream out("E:\XXXX.json");
    out << j.dump(4);
    out.close();
    

    反序列化Json数组到普通数组

    std::vector<std::string> vet;
    std::ifstream in("E:\XXXX.json");
    json j;
    in >> j;
    in.close();
    
    //获取一个数组的格式
    if (j.is_array()) {
        for (auto iter = j.begin(); iter != j.end(); ++iter) {
            std::string str = *iter;
            vet.emplace_back(str);
        }
    }
    for (auto &iter : vet) {
        std::cout << iter;
    }
    

    std::vector<std::string> vet;
    std::ifstream in("E:\XXXX.json");
    Json::Value value;
    Json::Reader reader;
    if (reader.parse(in, value)) {
        if (value.isArray()) {
            for (unsigned i = 0; i < value.size(); ++i) {
                std::string str = value[i].asString();
                vet.emplace_back(str);
            }
        }
    }
    in.close();
    
    for (auto &iter : vet) {
        std::cout << iter;
    }
    

    多层级字段的序列化与反序列化

    e.g.
    {
    	"opsSn": "Default string",
    	"diskSn": [
    		"testDisk1",
    		"testDisk2"
    	],
    	"memorySn": {
    		"bigSn": "testBig",
    		"middleSn": {
    			"smallSn": "testSmall"
    		}
    	}
    }
    

    数据序列化到Json

    nlohmann::json rootJson = nlohmann::json::object();
    
    //序列化diskSn
    std::vector<std::string> vet;
    vet.emplace_back("test1");
    vet.emplace_back("test2");
    nlohmann::json vetJson(vet);
    
    //序列化smallSn和middleSn
    nlohmann::json middleJson = nlohmann::json::object();
    middleJson["smallSn"] = "testSmall";
    
    //序列化bigSn和memorySn
    nlohmann::json memJson = nlohmann::json::object();
    memJson["bigSn"] = "testBig";
    
    //各层级节点挂载
    memJson["middleSn"] = middleJson;
    rootJson["opsSn"] = "Default string";
    rootJson["diskSn"] = vetJson;
    rootJson["memorySn"] = memJson;
    
    //序列化
    std::string str = rootJson.dump(4);
    
    std::cout << str;
    

    Json::Value rootValue = Json::objectValue;
    
    //序列化diskSn
    std::vector<std::string> vet;
    vet.emplace_back("test1");
    vet.emplace_back("test2");
    Json::Value vetValue = Json::arrayValue;
    for (auto &iter : vet) {
        vetValue.append(iter);
    }
    //或者
    //for (unsigned i = 0; i < vet.size(); ++i) {
    //    //vetValue[i] = vet[i];
    //}
    
    //序列化smallSn和middleSn
    Json::Value middleValue = Json::objectValue;
    middleValue["smallSn"] = "testSmall";
    
    //序列化bigSn和memorySn
    Json::Value memValue = Json::objectValue;
    memValue["bigSn"] = "testBig";
    
    //各层级节点挂载
    rootValue["opsSn"] = "Default string";
    memValue["middleSn"] = middleValue;
    rootValue["diskSn"] = vetValue;
    rootValue["memorySn"] = memValue;
    
    //序列化
    std::string str = rootValue.toStyledString();
    
    std::cout << str;
    

    备注:nlohmann::json在STL容器兼容方面很简便。无论是vector,set,map,deque,list等

    反序列化Json到数据

    std::ifstream in("E:\XXXX.json");
    std::string opsSn;
    std::vector<std::string> diskVet;
    std::string bigSn;
    std::string smallSn;
    
    try {
        nlohmann::json j = nlohmann::json::parse(in);
        in.close();
    
        //解析opsSn
        if (j.contains("opsSn") && j["opsSn"].is_string()) {
            opsSn = j.at("opsSn").get<std::string>();
        }
    
        //解析diskSn
        if (j["diskSn"].is_array()) {
            for (auto &iter : j["diskSn"]) {
                std::string str = iter;
                diskVet.emplace_back(str);
            }
        }
    
        //解析memorySn
        if (j["memorySn"].is_object()) {
            nlohmann::json memJson = j["memorySn"];
            if (memJson.contains("bigSn") && memJson["bigSn"].is_string()) {
                bigSn = memJson.at("bigSn").get<std::string>();
            }
            //解析middleSn
            if (memJson["middleSn"].is_object()) {
                nlohmann::json middleJson = memJson["middleSn"];
                if (middleJson.contains("smallSn") && middleJson["smallSn"].is_string()) {
                    smallSn = middleJson.at("smallSn").get<std::string>();
                }
            }
        }
    } catch (const std::exception&) {
    }
    
    std::cout << opsSn << std::endl;
    for (auto &iter : diskVet) {
        std::cout << iter << std::endl;
    }
    std::cout << bigSn << std::endl;
    std::cout << smallSn << std::endl;
    

    std::ifstream in("E:\XXXX.json");
    std::string opsSn;
    std::vector<std::string> diskVet;
    std::string bigSn;
    std::string smallSn;
    
    Json::Value value;
    Json::Reader reader;
    if (reader.parse(in, value)) {
        //解析opsSn
        if (value.isMember("opsSn") && value["opsSn"].isString()) {
            opsSn = value["opsSn"].asString();
        }
    
        //解析diskSn
        if (value["diskSn"].isArray()) {
            for (unsigned i = 0; i < value["diskSn"].size(); ++i) {
                std::string str = value["diskSn"][i].asString();
                diskVet.emplace_back(str);
            }
        }
    
        //解析memorySn
        if (value["memorySn"].isObject()) {
            Json::Value memValue = value["memorySn"];
            if (memValue.isMember("bigSn") && memValue["bigSn"].isString()) {
                bigSn = memValue["bigSn"].asString();
            }
            //解析middleSn
            if (memValue["middleSn"].isObject()) {
                Json::Value midSnValue = memValue["middleSn"];
                if (midSnValue.isMember("smallSn") && midSnValue["smallSn"].isString()) {
                    smallSn = midSnValue["smallSn"].asString();
                }
            }
        }
    }
    in.close();
    
    std::cout << opsSn << std::endl;
    for (auto &iter : diskVet) {
        std::cout << iter << std::endl;
    }
    std::cout << bigSn << std::endl;
    std::cout << smallSn << std::endl;
    

    备注:在解析json,两者没有明显的区别与优势

    Json对象里包含多个键值对(可能不知道主键,也拿到对应的值)

    e.g.
    {
    	"data":{
    	"test1":"this is test1",
    	"test2":"this is test2",
    	"test3":"this is test3",
    	"test4":"this is test4"
    	}
    }
    

    反序列化Json到数据

    std::ifstream in("E:\XXXX.json");
    json j;
    in >> j;
    in.close();
    
    std::map<std::string, std::string> dataMap;
    try {
        if (j["data"].is_object()) {
            nlohmann::json dataJson = j["data"];
            for (json::iterator it = dataJson.begin(); it != dataJson.end(); ++it) {
                std::string key = it.key();
                std::string val = it.value();
                dataMap.insert(std::pair<std::string, std::string>(key, val));
            }
        }
    } catch (const std::exception&) {
    }
    for (auto &iter : dataMap) {
        std::cout << iter.first << "  " << iter.second << std::endl;
    }
    

    std::ifstream in("E:\XXXX.json");
    std::map<std::string, std::string> dataMap;
    
    Json::Reader reader;
    Json::Value value;
    if (reader.parse(in, value)) {
        if (value["data"].isObject()) {
            Json::Value dataValue = value["data"];
            Json::Value::Members members = dataValue.getMemberNames();
            for (Json::Value::Members::iterator it = members.begin(); it != members.end(); ++it) {
                std::string key = *it;
                std::string val = dataValue[*it].asString();
                dataMap.insert(std::pair<std::string, std::string>(key, val));
            }
        }
    }
    in.close();
    for (auto &iter : dataMap) {
        std::cout << iter.first << "  " << iter.second << std::endl;
    }
    

    数据序列化到Json

    std::map<std::string, std::string> dataMap;
    dataMap.insert(std::pair<std::string, std::string>("test1", "this is test1"));
    dataMap.insert(std::pair<std::string, std::string>("test2", "this is test2"));
    dataMap.insert(std::pair<std::string, std::string>("test3", "this is test3"));
    dataMap.insert(std::pair<std::string, std::string>("test4", "this is test4"));
    
    //序列化data
    nlohmann::json j(dataMap);
    
    //层级挂载
    nlohmann::json rootJ = nlohmann::json::object();
    rootJ["data"] = j;
    
    std::cout << rootJ.dump(4);
    

    std::map<std::string, std::string> dataMap;
    dataMap.insert(std::pair<std::string, std::string>("test1", "this is test1"));
    dataMap.insert(std::pair<std::string, std::string>("test2", "this is test2"));
    dataMap.insert(std::pair<std::string, std::string>("test3", "this is test3"));
    dataMap.insert(std::pair<std::string, std::string>("test4", "this is test4"));
    
    //序列化data
    Json::Value dataValue = Json::objectValue;
    for (auto &iter : dataMap) {
        dataValue[iter.first] = iter.second;
    }
    //层级挂载
    Json::Value rootValue = Json::objectValue;
    rootValue["data"] = dataValue;
    
    std::cout << rootValue.toStyledString();
    

    Json与结构体的封装

    namespace ns {
    void to_json(json& j, const person& p) {
        j = json{ { "name", p.name },{ "address", p.address },{ "age", p.age } };
    }
    
    void from_json(const json& j, person& p) {
        j.at("name").get_to(p.name);
        j.at("address").get_to(p.address);
        j.at("age").get_to(p.age);
    }
    } // namespace ns
    

    优势:不需要知道person中成员的数据类型

  • 相关阅读:
    【uTenux实验】事件标志
    【uTenux实验】信号量
    【uTenux实验】任务管理
    【uTenux实验】写在开始实验之前
    Git撤销add、commit
    vim笔记
    Git使用方法(精心整理,绝对够用)
    git笔记三
    git笔记记录
    git笔记
  • 原文地址:https://www.cnblogs.com/gd-luojialin/p/14348173.html
Copyright © 2011-2022 走看看