首页 > 编程语言 >c++中nlohmann json的基本使用教程

c++中nlohmann json的基本使用教程

时间:2022-12-30 22:11:44浏览次数:41  
标签:hututu name c++ nlohmann json include cout

nlohmann/json 是一个C++实现的JSON解析器,使用非常方便直观,下面这篇文章主要给大家介绍了关于c++中nlohmann json基本使用的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下 <iframe data-google-container-id="a!2" data-google-query-id="COvtt72_ofwCFY06vAodeWwCyA" data-load-complete="true" data-mce-fragment="1" frameborder="0" height="280" id="aswift_1" marginheight="0" marginwidth="0" name="aswift_1" sandbox="allow-forms allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts allow-top-navigation-by-user-activation" scrolling="no" src="https://googleads.g.doubleclick.net/pagead/ads?client=ca-pub-6384567588307613&output=html&h=280&slotname=3921475131&adk=1931977407&adf=2062698613&pi=t.ma~as.3921475131&w=820&fwrn=4&fwrnh=100&lmt=1672408585&rafmt=1&format=820x280&url=https%3A%2F%2Fwww.jb51.net%2Farticle%2F261677.htm&fwr=0&rpe=1&resp_fmts=3&wgl=1&uach=WyJXaW5kb3dzIiwiMTAuMC4wIiwieDg2IiwiIiwiMTA4LjAuMTQ2Mi41NCIsW10sZmFsc2UsbnVsbCwiNjQiLFtbIk5vdD9BX0JyYW5kIiwiOC4wLjAuMCJdLFsiQ2hyb21pdW0iLCIxMDguMC41MzU5LjEyNSJdLFsiTWljcm9zb2Z0IEVkZ2UiLCIxMDguMC4xNDYyLjU0Il1dLGZhbHNlXQ..&dt=1672408584746&bpp=3&bdt=3415&idt=1020&shv=r20221207&mjsv=m202212010101&ptt=9&saldr=aa&abxe=1&cookie=ID%3D346c8b14597d3e9f-222bc50d43d600f7%3AT%3D1662463340%3ART%3D1662463340%3AS%3DALNI_MYffPK_GSMaQDwNU33CTdVpNHB4Cg&gpic=UID%3D00000983e0e519a4%3AT%3D1662463340%3ART%3D1669470849%3AS%3DALNI_MYe68xCjDXtW1mGc53EHZyY2l3qVg&prev_fmts=0x0&nras=1&correlator=1464164063979&frm=20&pv=1&ga_vid=1199527532.1672408586&ga_sid=1672408586&ga_hid=360538254&ga_fc=0&u_tz=480&u_his=1&u_h=1080&u_w=1920&u_ah=1040&u_aw=1920&u_cd=24&u_sd=1&dmc=8&adx=367&ady=775&biw=1903&bih=969&scr_x=0&scr_y=0&eid=44759875%2C44759926%2C44759837%2C31071167%2C44774606%2C44779794%2C44780792&oid=2&pvsid=3519017794703119&tmod=1829735726&wsm=1&uas=0&nvt=1&ref=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3D0E1I3SWSRj2kKSFKac4wxEEi3fYVKXdRUHLz0mCilrGvS7KTSFasPn6ZqCjUNMjw_N0BQ4M1_3rYugYJnZxfPa%26wd%3D%26eqid%3D99e58b6c001d371b0000000663aeedf8&eae=0&fc=1920&brdim=1283%2C-357%2C1283%2C-357%2C1920%2C-360%2C1914%2C1034%2C1920%2C969&vis=2&rsz=%7C%7CeEr%7C&abl=CS&pfx=0&fu=128&bc=31&ifi=2&uci=a!2&fsb=1&xpc=jppPClTFn7&p=https%3A//www.jb51.net&dtd=1031" width="820"></iframe> +

目录

一.json.hpp库下载及安装

1.1 开源地址及引入方法

nlohmann json的开源项目地址,其中有对json使用方法的详细说明:

https://github.com/nlohmann/json#serialization–deserialization

对于我们项目中要使用nlohmann json工具,只需要引入json.hpp这一个文件,其中包含所有接口函数,正如其文档中所述json.hpp文件在single_include/nlohmann目录下,我们只需要下载该文件即可:

git clone https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp

如上图片所示,使用json.hpp文件需要关注两点:

一是:#include <nlohmann/json.hpp>头文件路径的引入,这里将json.hpp文件放到linux系统中的/usr/local/include路径下,这是系统默认头文件路径,在编译时系统会自动查找该路径。我们在/usr/local/include路径下创建/nlohmann/json.hpp,如下图所示:

二是:在编译时需要指定c++11标准,-std=c++11。

1.2 demo程序测试

jsontest.cpp:

1 2 3 4 5 6 7 8 9 10 11 12 #include <iostream> #include <nlohmann/json.hpp>   //引入json.hpp,该文件已经放在系统默认路径:/usr/local/include/nlohmann/json.hpp using namespace std; // for convenience using json = nlohmann::json;   int main() {   auto config_json = json::parse(R"({"happy": true, "pi": 3.141})");  //构建json对象   cout << config_json << endl;   //输出json对象值   return 0; }

编译:

g++ jsontest.cpp -std=c++11

输出结果:

{“happy”:true,“pi”:3.141}

二.nlohmann json基本操作

2.1 由basic value创建json

两种方式创建json对象:赋值构造+直接构造

jsontest.cpp:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include <iostream> #include <nlohmann/json.hpp>   //引入json.hpp,该文件已经放在系统默认路径:/usr/local/include/nlohmann/json.hpp   using namespace std; using json = nlohmann::json;    // for convenience   int main() {   //方式一:赋值构造   json j1;   j1["name"]="LeBorn Jame";//字符串    j1["number"]=23;         //整数   j1["man"]=true;          //布尔值   j1["children"]={"LeBorn Jr","Bryce Maximus","Zhuri"};//数组   j1["behavior"]["funny"]="gigigigigigi";              //对象中元素值   j1["wife"]={{"name","Savannah Brinson"},{"man",false}};//对象       //方式二:直接构造   json j2={     {"name","LeBorn Jame"},     {"number",23},     {"man",true},     {"children",{"LeBorn Jr","Bryce Maximus","Zhuri"}},     {"behavior",{{"funny","gigigigigigi"}}},     {"wife",{{"name","Savannah Brinson"},{"man",false}}}   };     cout << "j1: "<<j1 << endl;   //输出json对象值   cout <<  "j2: "<<j2 << endl;   //输出json对象值   return 0; }

编译:

g++ jsontest.cpp -std=c++11

输出结果:

j1: {“behavior”:{“funny”:“gigigigigigi”},“children”:[“LeBorn Jr”,“Bryce Maximus”,“Zhuri”],“man”:true,“name”:“LeBorn Jame”,“number”:23,“wife”:{“man”:false,“name”:“Savannah Brinson”}}
j2: {“behavior”:{“funny”:“gigigigigigi”},“children”:[“LeBorn Jr”,“Bryce Maximus”,“Zhuri”],“man”:true,“name”:“LeBorn Jame”,“number”:23,“wife”:{“man”:false,“name”:“Savannah Brinson”}}

2.2 由json对象得到basic value

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include <iostream> #include <string>   #include <nlohmann/json.hpp>   //引入json.hpp,该文件已经放在系统默认路径:/usr/local/include/nlohmann/json.hpp   using namespace std;   using json = nlohmann::json;    // for convenience   int main() {   //构建一个json对象hututu   json hututu = {       {"name","hututu"},       {"age",18},       {"gender",'m'},       {"score",88.99},       {"location",{"aaa","bbb","ccc"}},   };   //方式一   auto name = hututu["name"].get<std::string>();  //获取“name”对应的value值,并转为string类型   cout<<"name = "<<name<<endl;   cout<<"type name = "<<typeid(name).name()<<endl;   cout<<"----------------------"<<endl;   //方式二   auto location0 = hututu["location"][0].get<std::string>();   auto location1 = hututu["location"][1].get<std::string>();   auto location2 = hututu["location"].at(2).get<std::string>();   cout<<"location0 = "<<location0<<endl;   cout<<"location1 = "<<location1<<endl;   cout<<"location2 = "<<location2<<endl;   return 0; }

输出结果:

name = hututu
type name = Ss
location0 = aaa
location1 = bbb
location2 = ccc

2.3 像操作stl container一样操作json value

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 #include <iostream> #include <string>   #include <nlohmann/json.hpp>   //引入json.hpp,该文件已经放在系统默认路径:/usr/local/include/nlohmann/json.hpp   using namespace std;   using json = nlohmann::json;    // for convenience   int main() {   //构建一个json对象animalArray   json animalArray={"cat","dog"};//定义一个数组类型的json对象   animalArray.push_back("pig");//添加元素   animalArray.emplace_back("duck");//C++11新方式添加元素,减少申请内存   cout<<"animalArray: "<<animalArray<<endl;   //使用is_array()函数判断对象类型,使用empty函数判断数量是否为空   if(animalArray.is_array() && !animalArray.empty())   {       auto size=animalArray.size();          //使用size函数获取元素数量       cout<<"animalArray size: "<<size<<endl;       auto animalLast=animalArray.at(size-1).get<std::string>();       cout<<"animalArray[size-1]: "<<animalLast<<endl;       cout<<"/--------------------/"<<endl;   }     json animalObject={{"kind","dog"},{"height",50}};//定义一个对象类型的json对象   animalObject.push_back({"color","red"});//插入元素   animalObject.erase("kind");//删除键值   cout<<"animalObject: "<<animalObject<<endl;   animalObject["height"] = 99;   //通过key修改value值   //判断是否含有某个键值方式一   if(animalObject.contains("height"))//通过contains函数判断是否包含某个key   {       auto height=animalObject["height"].get<double>();       cout<<"方式一:height: "<<height<<endl;   }   //判断是否含有某个键值方式二   auto size=animalObject.count("height");//通过count函数计算某一个键的数量   if(size>0)   {       cout<<"方式二:存在height键值"<<endl;   }   //判断是否含有某个键值方式三   auto iter=animalObject.find("height");//通过find函数查找某个键的迭代器   if(iter!=animalObject.end())   {       cout<<"方式三:存在height键值"<<endl;   }   //遍历输出键值方式1   cout<<"遍历输出键值方式1:"<<endl;   for(auto item:animalObject.items())   {       std::cout<<item.key()<<" "<<item.value()<<std::endl;   }   //遍历输出键值方式2   cout<<"遍历输出键值方式2:"<<endl;   for(auto iter=animalObject.begin();iter!=animalObject.end();++iter)   {       cout<<iter.key()<<" "<<iter.value()<<std::endl;   }   return 0; }

输出结果:

animalArray: [“cat”,“dog”,“pig”,“duck”]
animalArray size: 4
animalArray[size-1]: duck
/--------------------/
animalObject: {“color”:“red”,“height”:50}
方式一:height: 99
方式二:存在height键值
方式三:存在height键值
遍历输出键值方式1:
color “red”
height 99
遍历输出键值方式2:
color “red”
height 99

三.json序列化与反序列化

3.1 json value和string

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <iostream> #include <string>   #include <nlohmann/json.hpp>   //引入json.hpp,该文件已经放在系统默认路径:/usr/local/include/nlohmann/json.hpp   using namespace std;   using json = nlohmann::json;    // for convenience   int main() {   //反序列化构建json对象,两种方式   json hututu1 = "{\"name\":\"hututu\",\"age\":18,\"score\":88.99}"_json;//方式1,通过"_json"实现反序列化   auto temp = R"({"name":"hututu","age":18,"score":88.99})";//使用原生字符串关键字R来避免转移字符,但这一句并没有序列化,hututu2只保存字符串而已,需要结合方式3实现反序列化   json hututu2 = json::parse(temp);//方式2,通过静态函数"parse"实现反序列化   cout<<"/----------反序列化-----------/"<<endl;   cout<<"hututu1 = "<<hututu1<<endl;   cout<<"hututu2 = "<<hututu2<<endl;   cout<<"/----------序列化-----------/"<<endl;   //序列化(Serialization):dump(number),number为打印出的空格数   std::string hututu1_string=hututu1.dump();//animal1值为{"kind":"dog","height":50}   std::string hututu2_string=hututu2.dump(4);   cout<<"hututu1_string = "<<hututu1_string<<endl;   cout<<"hututu2_string = "<<hututu2_string<<endl;       return 0; }

输出结果:

/----------反序列化-----------/
hututu1 = {“age”:18,“name”:“hututu”,“score”:88.99}
hututu2 = {“age”:18,“name”:“hututu”,“score”:88.99}
/----------序列化-----------/
hututu1_string = {“age”:18,“name”:“hututu”,“score”:88.99}
hututu2_string = {
“age”: 18,
“name”: “hututu”,
“score”: 88.99
}

3.2 json对象和文件输入输出转换

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #include <iostream>        //文件操作头文件 #include <string> #include <fstream> #include <nlohmann/json.hpp>   //引入json.hpp,该文件已经放在系统默认路径:/usr/local/include/nlohmann/json.hpp   using namespace std;   using json = nlohmann::json;    // for convenience   int main() {   //上述操作适用于istream和ostream的子类,比如我们经常会用到的ifstream和ofstream   //从.json文件中读取内容到json对象中   std::ifstream in("./person.json");//打开文件,关联到流in   json hututu={"111","222"};      //定义一个json对象为hututu,有初始内容,但是会被覆盖   in>>hututu;                     //从流in中(也就是./person.json文件)读取内容到json对象中,会覆盖之前内容   in.close();                     //关闭文件流in   hututu["aaa"]="bbb";             //添加json对象内容   cout << hututu << endl;   //输出json对象值     //输出json对象内容到文件中,并生成新的文件   std::ofstream out("./new.json");    //创建文件./new.json,并关联到流out   hututu["name"]="new name";          //更改hututu对象的内容   out<<std::setw(4)<<hututu;          //输出json对象hututu信息到文件./new.json中,std::setw(4)用于设置增加打印空格   out.close();         //关闭文件流out     return 0; }

./person.json文件内容

{
“name”:“hututu”,
“age”:18,
“gender”:“m”,
“score”:88.99
}

执行程序后,输出的json对象内容如下,也就是从./person.json文件中读取的信息:

{“aaa”:“bbb”,“age”:18,“gender”:“m”,“name”:“hututu”,“score”:88.99}

同时在当前目录下生成新的文件./new.json,内容如下所示:

{
“aaa”: “bbb”,
“age”: 18,
“gender”: “m”,
“name”: “new name”,
“score”: 88.99
}

3.3 json value和自定义对象

在自定义对象命名空间中定义两个函数即可像basic value一样进行反序列化和序列化:from_json(const json& j,T& value)、to_json(json& j,const T& value)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 #include <iostream>        //文件操作头文件 #include <string> #include <nlohmann/json.hpp>   //引入json.hpp,该文件已经放在系统默认路径:/usr/local/include/nlohmann/json.hpp   using namespace std;   using json = nlohmann::json;   class person {     public:         person(){}       //默认构造函数         person(string m_name,int m_age,double m_score):name(m_name),age(m_age),score(m_score){};     public:       string name;       int age;       double score;     void display()     {       cout<<"person name = "<<this->name<<endl;       cout<<"person age = "<<this->age<<endl;       cout<<"person score = "<<this->score<<endl;     } }; //定义from_json(const json& j,T& value)函数,用于序列化 //json对象----->class对象 void from_json(const json& j,person& hututu) {     hututu.name=j["name"].get<std::string>();     hututu.age=j["age"].get<int>();     hututu.score=j["score"].get<double>(); }   //定义to_json(json& j,const T& value)函数,用于反序列化 //class对象----->json对象 void to_json(json& j,const person& hututu) {     j["name"]=hututu.name;     j["age"]=hututu.age;     j["score"]=hututu.score; } // 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); // }   //main.cpp文件 int main() {     person hututu{"hututu",18,88.99};//定义一个person对象为hututu     cout<<"/----------to json,方式1:json=class隐式转换-----------/"<<endl;     json j1=hututu;                //class to json,隐式调用to_json函数     cout<<"j1 = "<<j1<<endl;       //输出json对象值     cout<<"/----------to json,方式2:调用to_json函数-----------/"<<endl;     json j2;     to_json(j2,hututu);          //to json,调用to_json函数     cout<<"j2 = "<<j2<<endl;     //输出json对象值     cout<<"/----------from json,方式1:调用from_json函数-----------/"<<endl;     j1["name"]="new name";        //修改json对象数据     cout<<"new j1 = "<<j1<<endl;        //输出json对象值     person hututu_new;     from_json(j1,hututu_new);   //json---->class     hututu_new.display();     //输出person对象内容     cout<<"/----------from json,方式2:调用.get函数-----------/"<<endl;     person hututuNew = j2.get<person>();//像basic value一样通过get函数获取值,将其值直接赋值给自定义对象     hututuNew.display();     return 0; }

执行结果:

/----------to json,方式1:json=class隐式转换-----------/
j1 = {“age”:18,“name”:“hututu”,“score”:88.99}
/----------to json,方式2:调用to_json函数-----------/
j2 = {“age”:18,“name”:“hututu”,“score”:88.99}
/----------from json,方式1:调用from_json函数-----------/
new j1 = {“age”:18,“name”:“new name”,“score”:88.99}
person name = new name
person age = 18
person score = 88.99
/----------from json,方式2:调用.get函数-----------/
person name = hututu
person age = 18
person score = 88.99

四.NLOHMANN_DEFINE_TYPE_INTRUSIVE宏的使用

4.1 宏的定义

JSON for Modern C++ 中为方便序列化和反序列化定义了两宏,如下

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(name, member1, member2, …) 将在要为其创建代码的类/结构的命名空间内定义。
NLOHMANN_DEFINE_TYPE_INTRUSIVE(name, member1, member2, …) 将在要为其创建代码的类/结构中定义。 该宏还可以访问私有成员。

进一步查看代码:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 /*! @brief macro @def NLOHMANN_DEFINE_TYPE_INTRUSIVE @since version 3.9.0 */ #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...)  \     friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \     friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }   /*! @brief macro @def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE @since version 3.9.0 */ #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...)  \     inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \     inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }

4.2 宏的使用

可以看出上述的宏主要实现了from_json和to_json两个函数的功能,使用时需要在一个类中调用该宏,并传入(类名,参数1,参数2,参数3…)使用,这样在json对象和class对象之间之间直接赋值可以完成相互转换,具体用法如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include <iostream>        //文件操作头文件 #include <string> #include <nlohmann/json.hpp>   //引入json.hpp,该文件已经放在系统默认路径:/usr/local/include/nlohmann/json.hpp   using namespace std;   using json = nlohmann::json;   class person {    public:       string name;       int age;       double score;       void display()       {         cout<<"person name = "<<this->name<<endl;         cout<<"person age = "<<this->age<<endl;         cout<<"person score = "<<this->score<<endl;       }       // 类名,成员1,成员2,成员3       NLOHMANN_DEFINE_TYPE_INTRUSIVE(person, name, age, score); };   //main.cpp文件 int main() {     person hututu{"hututu",18,88.99};//定义一个person对象为hututu     cout<<"/----------调用宏实现:to json-----------/"<<endl;     json j1 = hututu;     cout << j1<< endl;     cout << j1.dump() << endl;     cout<<"/----------调用宏实现:from json-----------/"<<endl;     j1["name"]="new name";     person hututu_new = j1;     hututu_new.display();       return 0; }

输出结果:

/----------调用宏实现:to json-----------/
{“age”:18,“name”:“hututu”,“score”:88.99}
{“age”:18,“name”:“hututu”,“score”:88.99}
/----------调用宏实现:from json-----------/
person name = new name
person age = 18
person score = 88.99

标签:hututu,name,c++,nlohmann,json,include,cout
From: https://www.cnblogs.com/lidabo/p/17015911.html

相关文章