rapidjson超级好用,只需要包含头文件,也就是可以跨平台
虽然写很复杂的功能的时候可能需要自己封装一些接口,但是写简单的json解析完全够用了
rapidjson封装和解析
不多说,直接上代码(可以忽略操作文件的步骤),代码包含多种情况的json格式,搞清楚下面的几种格式,基本没什么问题了。
#include <iostream> #include <string> #include <fstream> //包含rapidjson必要头文件,rapidjson文件夹拷贝到工程目录,或者设置include路径,或者加入到工程树 #include "rapidjson/document.h" #include "rapidjson/filereadstream.h" #include "rapidjson/filewritestream.h" #include "rapidjson/prettywriter.h" #include "rapidjson/stringbuffer.h" using namespace std; using namespace rapidjson; //引入rapidjson命名空间 //写json文件 void json_write() { Document doc; doc.SetObject(); Document::AllocatorType &allocator=doc.GetAllocator(); //获取分配器 //1.添加字符串成员 doc.AddMember("author","tashaxing",allocator); //2.添加数组成员 Value array1(kArrayType); //kArrayType 枚举成员 表示数组 for(int i=0;i<3;i++) { Value int_object(kObjectType); int_object.SetInt(i); array1.PushBack(int_object,allocator); } doc.AddMember("number",array1,allocator); //3.添加复合对象 Value object(kObjectType); //kObjectType枚举成员 表示对象 object.AddMember("language1","C++",allocator); object.AddMember("language2","java",allocator); doc.AddMember("language",object,allocator); //4.添加对象数组和复合对象的组合 Value array2(kArrayType); Value object1(kObjectType); object1.AddMember("hobby","drawing",allocator); array2.PushBack(object1,allocator); Value object2(kObjectType); object2.AddMember("height",1.71,allocator); array2.PushBack(object2,allocator); doc.AddMember("information",array2,allocator); StringBuffer buffer; //PrettyWriter<StringBuffer> pretty_writer(buffer); //PrettyWriter是格式化的json(自动换行) Writer<StringBuffer> pretty_writer(buffer); //Writer则是换行空格压缩后的json (换行和空格忽视) doc.Accept(pretty_writer); //打印到屏幕 cout<<"the json output:"<<endl; cout<<buffer.GetString()<<endl; //输出到文件 ofstream fout; fout.open("test"); //可以使绝对和相对路径,用\\隔开目录,test, test.json, test.txt 都行,不局限于文件格式后缀,只要是文本文档 fout<<buffer.GetString(); fout.close(); } //读json文件 void json_read() { cout<<"the json read:"<<endl; ifstream fin; fin.open("test"); string str; string str_in=""; while(getline(fin,str)) //一行一行地读到字符串str_in中 { str_in=str_in+str+'\n'; } //解析并打印出来 Document document; document.Parse<0>(str_in.c_str()); Value &node1=document["author"]; cout<<"author: "<<node1.GetString()<<endl; Value &node2=document["number"]; cout<<"number: "<<endl; if(node2.IsArray()) { for(int i=0;i<node2.Size();i++) cout<<'\t'<<node2[i].GetInt()<<endl; } Value &node3=document["language"]; //<<<这里要特别注意,取对象>>> cout<<"language: "<<endl; Value &tmp=node3["language1"]; //<<<这里是取子对象>>> cout<<'\t'<<"language1: "<<tmp.GetString()<<endl; //<<<取子对象成员>>> tmp=node3["language2"]; cout<<'\t'<<"language2: "<<tmp.GetString()<<endl; Value &node4=document["information"]; cout<<"information: "<<endl; if(node4.IsArray()) { int i=0; Value &data=node4[i]; //注意,此处下表索引只能用变量,不能用常量,例如node[0]编译错误 cout<<'\t'<<"hobby: "<<data["hobby"].GetString()<<endl; i=1; data=node4[i]; cout<<'\t'<<"height: "<<data["height"].GetDouble()<<endl; } } int main(int argc,char **argv) { //写、读 测试 json_write(); json_read(); return 0; }运行结果( PrettyWriter):
the json output: { "author": "tashaxing", "number": [ 0, 1, 2 ], "language": { "language1": "C++", "language2": "java" }, "information": [ { "hobby": "drawing" }, { "height": 1.71 } ] } the json read: author: tashaxing number: 0 1 2 language: language1: C++ language2: java information: hobby: drawing height: 1.71
运行结果( Writer):
the json output: {"author":"tashaxing","number":[0,1,2],"language":{"language1":"C++","language2":"java"},"information":[{"hobby":"drawing"},{"height":1.71}]} the json read: author: tashaxing number: 0 1 2 language: language1: C++ language2: java information: hobby: drawing height: 1.71
还有一种方法可以封装Json格式字符串:
#include "rapidjson/document.h" #include "rapidjson/writer.h" #include "rapidjson/stringbuffer.h" #include "rapidjson/prettywriter.h" #include <iostream> #include <vector> #include <string> using namespace std; using namespace rapidjson; // json格式:{"RetCd":"0","RetMsg":"","row1":[{"key":1,"name":"aa"},...]} struct AA{ int a; string b; }; int main() { vector<AA> para; AA a; a.a = 1; a.b = "aa"; para.push_back(a); a.a = 2; a.b = "bb"; para.push_back(a); a.a = 3; a.b = "cc"; para.push_back(a); //开始 StringBuffer buffer; //Writer<StringBuffer> writer(buffer); PrettyWriter<StringBuffer> writer(buffer); writer.StartObject(); //根对象 开始 writer.Key("RetCd"); //键 writer.String("0"); //值 writer.Key("RetMsg"); writer.String(""); writer.Key("row1"); writer.StartArray(); //数组 开始 //.... for(int i = 0;i < para.size();i++){ writer.StartObject(); //子对象 开始 writer.Key("key"); writer.Int(para[i].a); writer.Key("name"); writer.String(para[i].b.c_str()); writer.EndObject(); //子对象 结束 } writer.EndArray(); //数组 结束 writer.EndObject(); //根对象 结束 printf("%s\n",buffer.GetString()); return 0; }
运行结果:
{ "RetCd": "0", "RetMsg": "", "row1": [ { "key": 1, "name": "aa" }, { "key": 2, "name": "bb" }, { "key": 3, "name": "cc" } ] }
补充几个json的概念:
(1)标准json和非标准json:
标准json要求键必须都是双引号的字符串,而非标准json可以单引号。
例如:
{a : 'abc'}
{'a' : 'abc'}
{a : "abc"}
{"a" : "abc"}
只有第4个是标准json
(2)json中的[]与{}:
在 JSON 里 [] 是 Array {} 是Ojbect
[] Array 的key 是 int 从0算起
{} 的key 是 string