C++ JSON库的使用

版权声明:人工智能/机器学习/深度学习交流QQ群:811460433 , 微信公众号:程序员深度学习 https://blog.csdn.net/sinat_24143931/article/details/84974154
人工智能/机器学习/深度学习交流QQ群:116270156
也可以扫一扫下面二维码加入微信群,如果二维码失效,可以添加博主个人微信,拉你进群

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++、C#、Java、JavaScript、Perl、Python等)。这些特性使JSON成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成(一般用于提升网络传输速率)。

今天介绍的json版本是在c++下使用的,是一个开源项目。
GitHub开源项的地址:https://github.com/nlohmann/json
json for modern c++是一个德国大牛nlohmann写的,该版本的json有以下特点:
1.直观的语法。
2.整个代码由一个头文件组成json.hpp,没有子项目,没有依赖关系,没有复杂的构建系统,使用起来非常方便。
3.使用c++11标准编写。
4.使用json 像使用STL容器一样。
5.STL和json容器之间可以相互转换。

1. 如何使用?

将github上的src文件夹里的json.hpp头文件下载保存到当前目录中。
在代码中包含json.hpp头文件并引入json作用域

#include "json.hpp"
using json = nlohmann::json;

2. 常用方法

2.1 创建json对象

2.1.1 使用cin,cout输入输出流

json提供了cin,cout的输入输出流的操作符。但需要注意的是,cin要有ctr + D结束输入。cout会自动把json转换为string。

#include <iostream>
#include "json.hpp"
using json = nlohmann::json;
using std::cout;
using std::endl;
using std::cin;

int main(int argc, const char * argv[]) {
    json temp;
    cin >> temp;
    cout << temp << endl;
    return 0;
}
/*
输入:
{
  "pi": 3.141,
  "happy": true,
  "name": "Niels",
  "nothing": null,
  "answer": {
    "everything": 42
  },
  "list": [1, 0, 2],
  "object": {
    "currency": "USD",
    "value": 42.99
  }
}
{"answer":{"everything":42},"happy":true,"list":[1,0,2],"name":"Niels","nothing":null,"object":{"currency":"USD","value":42.99},"pi":3.141}
Program ended with exit code: 0
*/

2.1.2 提供根据键直接生成键值对的方法

#include <iostream>
#include "json.hpp"
using json = nlohmann::json;
using std::cout;
using std::endl;
using std::cin;

int main(int argc, const 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 << endl;
    cout << endl;
    cout << j2 << endl;
    return 0;
}
/*
{"answer":{"everything":42},"happy":true,"list":[1,0,2],"name":"Niels","nothing":null,"object":{"currency":"USD","value":42.99},"pi":3.141}

{"answer":{"everything":42},"happy":true,"list":[1,0,2],"name":"Niels","nothing":null,"object":{"currency":"USD","value":42.99},"pi":3.141}
Program ended with exit code: 0
*/

2.1.3 json::array json::object

在所有上述情况下,你不需要“告诉”编译器要使用哪个JSON值。如果你想明确或表达一些边缘的情况下,可以使用json::array,json::object。

#include <iostream>
#include "json.hpp"
using json = nlohmann::json;
using std::cout;
using std::endl;
using std::cin;

int main(int argc, const 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"}), json::array({"value", 42.99}) };
    for (auto object : array_not_object) {
        cout << object << endl;
    }
    return 0;
}

2.1.4 几个区别

  1. array是一个数组,可以用数字直接下标访问。
json array = {
        "yan",12,"ze",13
    };
cout << array[0] << endl;
  1. array是一个数组里面放了一个数组。认为”yan”,12是数组里面的两个元素。
json array = {
        {"yan",12},
        "ze",13
    };
cout << array[0][0] << endl;
  1. array是数组里面有一个数组(里面包含了一个键值对)。
json array = {
        {{"yan",12}},
        "ze",13
    };
cout << array[0]["yan"] << endl;
  1. array里面含有两个键值对。
json array = {
        {"yan",12},
        {"ze",13}
    };
cout << array["yan"] << endl;
  1. array里面含有两个数组,数组里面分别有一个键值对。
json array = {
        {
            {"yan",12}
        },
        {
            {"ze",13}
        }
    };
cout << array[0]["yan"] << endl;

(注意区分{}的位置来判断对象的性质)。

如果实在判断不出来,可以用C++11的for语句,看每一个输出结果的符号来判断每一个对象的性质。

2.2 序列化

将json对象序列化,成为字符串

2.2.1 标准输出自动序列化

json j
std :: cout << j;
// setw操纵器被重载以设置漂亮打印的缩进 
std :: cout << std :: setw( 4<< j << std :: endl;

2.2.2 使用dump()函数

//显式转换为string 
std::string s = j.dump();    // {\"happy\":true,\"pi\":3.141}

//序列化与漂亮的打印
//传入空格的数量缩进 
std::cout << j.dump(4) << std::endl;
// 输出:
//{
//     "happy": true,
//     "pi": 3.141
// }

2.3 反序列化

将数据流转化为json对象

2.3.1 从标准输入反序列化

json j
std :: cin >> j;

2.3.2 通过附加_json到字符串文字来创建对象实现反序列化

//从字符串文字创建对象 
json j = " { \" happy \":true,\" pi \":3.141} " _json;

//或者原始字符串文字
auto j2 = R"(
   { 
    "happy":true,
    "pi":3.141 
  } 
)" _json;

请注意,没有附加_json后缀,传递的字符串文字不会被解析,而只是用作JSON字符串值。也就是说,json j = "{ “happy”: true, “pi”: 3.141 }“只存储字符串”{ “happy”: true, “pi”: 3.141 }"而不是解析实际的对象。

2.3.3 使用json::parse()函数

//明确解析
auto j3 = json::parse(" { \" happy \":true,\" pi \":3.141} ");

2.3.4 从迭代器范围读取

您还可以从迭代器范围读取JSON; 也就是说,可以从其内容存储为连续字节序列的迭代器访问的任何容器,例如std::vector

std :: vector < uint8_t > v = { ' t ',' r ',' u ',' e ' };
json j = json :: parse(v.begin(),v.end());

//或
std :: vector < uint8_t > v = { ' t ',' r ',' u ',' e ' };
json j = json :: parse(v);

2.3 与STL适应

json提供了许多和STL类似的操作方法:

#include <iostream>
#include "json.hpp"
using json = nlohmann::json;
using std::cout;
using std::endl;
using std::cin;

int main(int argc, const char * argv[]) {
    // create an array using push_back
    json j;
    j.push_back("foo");
    j.push_back(1);
    j.push_back(true);

    // iterate the array
    for (json::iterator it = j.begin(); it != j.end(); ++it) {
        std::cout << *it << '\n';
    }

    // range-based for
    for (auto element : j) {
        std::cout << element << '\n';
    }

    // getter/setter
    const std::string tmp = j[0];
    j[1] = 42;
    bool foo = j.at(2);

    // other stuff
    j.size();     // 3 entries
    j.empty();    // false
    j.type();     // json::value_t::array
    j.clear();    // the array is empty again

    // convenience type checkers
    j.is_null();
    j.is_boolean();
    j.is_number();
    j.is_object();
    j.is_array();
    j.is_string();

    // comparison
    cout << (j == "[\"foo\", 1, true]"_json) << endl;  // true

    // create an object
    json o;
    o["foo"] = 23;
    o["bar"] = false;
    o["baz"] = 3.141;

    // special iterator member functions for objects
    for (json::iterator it = o.begin(); it != o.end(); ++it) {
        std::cout << it.key() << " : " << it.value() << "\n";
    }

    // find an entry
    if (o.find("foo") != o.end()) {
        // there is an entry with key "foo"
        cout << *o.find("foo") << endl;
    }

    // or simpler using count()
    int foo_present = o.count("foo"); // 1
    int fob_present = o.count("fob"); // 0
    cout << foo_present << endl;
    cout << fob_present << endl;
    // delete an entry
    o.erase("foo");
    cout << (o.find("foo") == o.end()) << endl;
    return 0;
}

2.4 STl与json转换

允许把STL与json相转换。

#include <iostream>
#include <deque>
#include <list>
#include <forward_list>
#include <set>
#include <unordered_set>
#include "json.hpp"
using json = nlohmann::json;
using std::cout;
using std::endl;
using std::cin;

int main(int argc, const char * argv[]) {
    std::vector<int> c_vector {1, 2, 3, 4};
    json j_vec(c_vector);
    // [1, 2, 3, 4]

    std::deque<double> c_deque {1.2, 2.3, 3.4, 5.6};
    json j_deque(c_deque);
    // [1.2, 2.3, 3.4, 5.6]

    std::list<bool> c_list {true, true, false, true};
    json j_list(c_list);
    // [true, true, false, true]

    std::forward_list<int64_t> c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543};
    json j_flist(c_flist);
    // [12345678909876, 23456789098765, 34567890987654, 45678909876543]

    std::array<unsigned long, 4> c_array {{1, 2, 3, 4}};
    json j_array(c_array);
    // [1, 2, 3, 4]

    std::set<std::string> c_set {"one", "two", "three", "four", "one"};
    json j_set(c_set); // only one entry for "one" is used
    // ["four", "one", "three", "two"]

    std::unordered_set<std::string> c_uset {"one", "two", "three", "four", "one"};
    json j_uset(c_uset); // only one entry for "one" is used
    // maybe ["two", "three", "four", "one"]

    std::multiset<std::string> c_mset {"one", "two", "one", "four"};
    json j_mset(c_mset); // only one entry for "one" is used
    // maybe ["one", "two", "four"]

    std::unordered_multiset<std::string> c_umset {"one", "two", "one", "four"};
    json j_umset(c_umset); // both entries for "one" are used
    // maybe ["one", "two", "one", "four"]
    return 0;
}

对于关联容器,json直接把map中的键值对转化为json的object。

std::map<std::string, int> c_map { {"one", 1}, {"two", 2}, {"three", 3} };
json j_map(c_map);
// {"one": 1, "three": 3, "two": 2 }

std::unordered_map<const char*, double> c_umap { {"one", 1.2}, {"two", 2.3}, {"three", 3.4} };
json j_umap(c_umap);
// {"one": 1.2, "two": 2.3, "three": 3.4}

std::multimap<std::string, bool> c_mmap { {"one", true}, {"two", true}, {"three", false}, {"three", true} };
json j_mmap(c_mmap); // only one entry for key "three" is used
// maybe {"one": true, "two": true, "three": true}

std::unordered_multimap<std::string, bool> c_ummap { {"one", true}, {"two", true}, {"three", false}, {"three", true} };
json j_ummap(c_ummap); // only one entry for key "three" is used
// maybe {"one": true, "two": true, "three": true}

json还提供隐式类型转换。

/// strings
std::string s1 = "Hello, world!";
json js = s1;
std::string s2 = js;

// Booleans
bool b1 = true;
json jb = b1;
bool b2 = jb;

// numbers
int i = 42;
json jn = i;
double f = jn;

// etc.

也可以使用显式类型转换。

std::string vs = js.get<std::string>();
bool vb = jb.get<bool>();
int vi = jn.get<int>();
// etc.

2.5 json最重要的还是设计config文件

例如以下:

json question = {
    {"question",{
        {
            {"id",0},
            {"choice_type","single"},
            {"grading",{
                {"max_grade",10},
                {"half_grade",5}
            }},
            {"standard_answer",{1}},
            {"description","this is a test for choice judger"},
            {"choice",{
                {
                    {"id",0},
                    {"description","nope"}
                },
                {
                    {"id",1},
                    {"description","B"}
                },
                {
                    {"id",2},
                    {"descrition","C"}
                },
                {
                    {"id",3},
                    {"description","D"}
                }
            }
            }
        },
        {
            {"id",1},
            {"choice_type","double"},
            {"grading",{
                {"max_grade",10},
                {"half_grade",5}
            }},
            {"standard_answer",{1, 2}},
            {"description","this is a test for choice judger"},
            {"choice",{
                {
                    {"id",0},
                    {"description","nope"}
                },
                {
                    {"id",1},
                    {"description","B"}
                },
                {
                    {"id",2},
                    {"descrition","C"}
                },
                {
                    {"id",3},
                    {"description","D"}
                }
            }
            }
        },
        {
            {"id",2},
            {"choice_type","multi"},
            {"grading",{
                {"max_grade",10},
                {"half_grade",5}
            }},
            {"standard_answer",{1,2}},
            {"description","this is a test for choice judger"},
            {"choice",{
                {
                    {"id",0},
                    {"description","nope"}
                },
                {
                    {"id",1},
                    {"description","B"}
                },
                {
                    {"id",2},
                    {"descrition","C"}
                },
                {
                    {"id",3},
                    {"description","D"}
                }
            }
            }
        }
    }
    },
    {"description","this is choice questions!"}
};
json answer = {
    {
        {"question_id",1},
        {"choice_id",{1}}
    },
    {
        {"question_id",0},
        {"choice_id",{1}}
    },
    {
        {"question_id",2},
        {"choice_id",{1,2,3}}
    }
};

最后

欢迎大家扫一扫下面二维码加入微信交流群,如果二维码失效,可以添加博主个人微信,拉你进群

猜你喜欢

转载自blog.csdn.net/sinat_24143931/article/details/84974154