JSON for Modern C++是一个简单且强大的json处理库,只需要包含一个头文件便可使用。

本文代码说明:单行注释解释代码,多行注释展示输出。

简单介绍

JSON for Modern C++有如下特点:

  • 语法直观,容易理解
  • 集成至一个库文件,使用方便
  • 代码经过严格测试,质量高

使用简介

JSON as first-class data type

#include <iostream>
#include <fstream>
#include <iomanip>
#include "json.hpp"

using namespace std;
using json = nlohmann::json;

int main(int argc, char **argv) {
    // create an empty structure (null)
    json j;

    // add a number that is stored as double (note the implicit conversion of j to an object)
    j["pi"] = 3.141;

    // add a Boolean that is stored as bool
    j["happy"] = true;

    // add a string that is stored as std::string
    j["name"] = "Niels";

    // add another null object by passing nullptr
    j["nothing"] = nullptr;

    // add an object inside the object
    j["answer"]["everything"] = 42;

    // add an array that is stored as std::vector (using an initializer list)
    j["list"] = {1, 0, 2};

    // add another object (using an initializer list of pairs)
    j["object"] = {{"currency", "USD"},
                   {"value",    42.99}};

    // instead, you could also write (which looks very similar to the JSON above)
    json j2 = {
            {"pi",      3.141},
            {"happy",   true},
            {"name",    "Niels"},
            {"nothing", nullptr},
            {"answer",  {
                                {"everything", 42}
                        }},
            {"list",    {       1, 0, 2}},
            {"object",  {
                                {"currency",   "USD"},
                                   {"value", 42.99}
                        }}
    };

    cout << j.dump(4) << endl;
    cout << j2.dump(4) << endl;
    /*  相同的输出:
    {
        "answer": {
            "everything": 42
        },
        "happy": true,
        "list": [
            1,
            0,
            2
        ],
        "name": "Niels",
        "nothing": null,
        "object": {
            "currency": "USD",
            "value": 42.99
        },
        "pi": 3.141
    }
    */
    return 0;
}

一般情况无需声明json的值类型,但也支持显示声明特定的值类型:

#include <iostream>
#include <fstream>
#include <iomanip>
#include "json.hpp"

using namespace std;
using json = nlohmann::json;

int main(int argc, char **argv) {
    // a way to express the empty array []
    json empty_array_explicit = json::array();

    // ways to express the empty object {}
    json empty_object_implicit = json({});      //隐式使用
    json empty_object_explicit = json::object();//显示使用

    // a way to express an _array_ of key/value pairs [["currency", "USD"], ["value", 42.99]]
    json array_not_object = json::array({ {"currency", "USD"}, {"value", 42.99} });
    cout << array_not_object.dump(4) << endl;
    /*
    [
        [
            "currency",
            "USD"
        ],
        [
            "value",
            42.99
        ]
    ]
     */
    return 0;
}

Serialization / Deserialization(序列号/反序列化)

  1. json与string类型的转换

    #include <iostream>
    #include <fstream>
    #include <iomanip>
    #include "json.hpp"
    
    using namespace std;
    using json = nlohmann::json;
    
    int main(int argc, char **argv) {
        // create object from string literal
        json j = "{ \"happy\": true, \"pi\": 3.141 }"_json;
    
        // or even nicer with a raw string literal
        auto j2 = R"(
        {
            "happy": true,
            "pi": 3.141
        }
        )"_json;
    
        // parse explicitly
        auto j3 = json::parse("{ \"happy\": true, \"pi\": 3.141 }");
    
        cout << j.dump() << endl;
        cout << j2.dump() << endl;
        cout << j3.dump() << endl;
        /*
        {"happy":true,"pi":3.141}
        {"happy":true,"pi":3.141}
        {"happy":true,"pi":3.141}
         */
        return 0;
    }
    

    序列号与赋值的区别:

    #include <iostream>
    #include <fstream>
    #include <iomanip>
    #include "json.hpp"
    
    using namespace std;
    using json = nlohmann::json;
    
    int main(int argc, char **argv) {
        // store a string in a JSON value
        json j_string = "this is a string";
    
        // retrieve the string value
        auto cpp_string = j_string.get<std::string>();
        // retrieve the string value (alternative when an variable already exists)
        std::string cpp_string2;
        j_string.get_to(cpp_string2);
    
        // retrieve the serialized value (explicit JSON serialization)
        std::string serialized_string = j_string.dump();
    
        // output of original string
        std::cout << cpp_string << " == " << cpp_string2 << " == " << j_string.get<std::string>() << '\n';
        // output of serialized value
        std::cout << j_string << " == " << serialized_string << std::endl;
        /*
        this is a string == this is a string == this is a string
        "this is a string" == "this is a string"
         */
        return 0;
    }
    

    dump()函数返回最初存储的字符串的值

    注意:该库仅支持UTF-8,当在库中存储不同编码的字符串时,调用dump()可能会抛出异常,除非异常json::error_handler_t::replace或json::error_handler_t::ignore被错误处理程序正确处理。

  2. json与stream类型的转换

    #include <iostream>
    #include <fstream>
    #include <iomanip>
    #include "json.hpp"
    
    using namespace std;
    using json = nlohmann::json;
    
    int main(int argc, char **argv) {
        // deserialize from standard input
        json j;
        std::cin >> j;
    
        // serialize to standard output
        std::cout << j << endl;
    
        // the setw manipulator was overloaded to set the indentation for pretty printing
        std::cout << std::setw(4) << j << std::endl;
    
        /*
        {"happy":true,"pi":3.141}
        {"happy":true,"pi":3.141}
        {
            "happy": true,
            "pi": 3.141
        }
         */
    
        // read a JSON file
        std::ifstream i("file.json");
        json j;
        i >> j;
    
        // write prettified JSON to another file
        std::ofstream o("pretty.json");
        o << std::setw(4) << j << std::endl;
        return 0;
    }
    
  3. 根据迭代器范围读取json

    如果迭代器的value_type是一个1、2或4字节的整型类型,那么它将分别被解释为UTF-8、UTF-16和UTF-32。

    #include <iostream>
    #include <fstream>
    #include <iomanip>
    #include "json.hpp"
    
    using namespace std;
    using json = nlohmann::json;
    
    int main(int argc, char **argv) {
        std::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'};
        json j = json::parse(v.begin(), v.end());
        json j2 = json::parse(v);
        cout << j.dump() << endl;
        cout << j2.dump() << endl;
        /*
        true
        true
         */
        return 0;
    }
    
  4. 其他使用

    1. 自定义容器和迭代器
    2. SAX接口

参考资料

项目地址:JSON for Modern C++

json支持:json官网