rapidjson 入门-1
//////////////////////////////////////////////////////////////////////////// //1. Parse a JSON text string to a document. const char json[] = "{" ""name": "Obama"," ""null": null," ""int": 6," ""double": 3.14," ""bool": true," ""array": [5,6,7,8]" "}"; /** *json的数据类型有number,String,null,bool。Object,array number可以是任何类型数字,数组的成员也可以是任何类型。由于c++ 的限制,我们会在解析器中扩展出number的int,unsigned int,double,等等 他们都属于number. json的键只可以是String。不管什么类型的数据,亦或是键,他们都属于value类型 */ Document document; document.Parse(json);//解析 assert(!document.HasParseError());//查看是否有创建错误 //遍历表 for (auto b =document.MemberBegin(); b != document.MemberEnd(); ++b) { std::cout <<b->name.GetString()<<" ";//键依然是value类型 std::cout <<b->value.IsArray()<<b->value.IsNumber()<<b->value.IsString()<<b->value.IsBool();//可以发现json的值都保存在Value中 } std::cout <<std::endl; /************************************************************************/ /* 跟节点的数据类型 早期的json版本,根节点数据只可以是数组或者Object,不过在最新版的json 中,支持所有类型作为根节点 */ /************************************************************************/ assert(document.IsObject()); //assert(document.IsArray());导致断言 /************************************************************************/ /*索引值 支持下标和find操作 下标强制返回value的引用,find 返回键值对的迭代器 auto & ref =document["name"]; auto iter =document.findMember("name"); */ /************************************************************************/ auto& ref = document["name"];//强制引用 auto iter =document.FindMember("name"); std::cout <<ref.GetString()<<std::endl; std::cout << iter->name.GetString() <<iter->value.GetString();//迭代了键值对,name是一个固定String类型的value std::cout <<std::endl; /************************************************************************/ /* 获取值 可以用value::get***函数来获取value的具体值 */ /************************************************************************/ /************************************************************************/ /* 判断值 Value::is***函数来判断具体类型 */ /************************************************************************/ /************************************************************************/ /* 设定值 Value::set***可以设定修改某个键的值,值的类型可以变. document也是一个Value。 document在建立之初,我们可以为之设定一个初始值
document.SetObject(); */ /************************************************************************/ auto& dou =document["double"]; dou.SetString("3.14"); /************************************************************************/ /* 遍历修改增加数组的值 */ /************************************************************************/ auto& arr =document["array"]; for (auto b = arr.Begin(); b != arr.End(); ++b)//数组的成员依然是value,并且数据结构是Vector { std::cout<< b->GetInt(); } for (int i = 0; i < arr.Size(); ++i)//既然是vector,那么就支持下标操作 { arr[i].SetInt(6); } //插入弹出--popBack arr.PushBack(8/*创建一个Value*/,document.GetAllocator());//显示传递内存分配器,一般标准库容器作为模板实参,其默认值都会失效 arr.PushBack(Value("啦啦啦"),document.GetAllocator()); //我们需要显式指定allocator /************************************************************************/ /* 数字 数字在调用getdouble时候会发生自动转换。对于int,unsigned int,double,可以无损转换 但是int64会使数据丢失*/ /************************************************************************/ std::cout <<std::endl; /************************************************************************/ /* 比较 很幸运的是,value重载了== !=比较操作符,于是我们不必麻烦的用get函数之后再比较*/ /************************************************************************/ bool isS = ref =="Obama";//true dou.SetDouble(3.14); bool isD = dou != 3; /************************************************************************/ /*Value的右值语意 对于value的赋值操作符 = addMember pushBack 他们的参数都是一个右值引用,于是,原来的值会被搬移到新的地方,而原来的值会变成null 对于现代的编译器,他们大多数都会有右值的优化,如果函数返回一个临时对象,外边还有人接受的话 那么就会由默认的右值语意,对于函数的形参也是一个道理。不过对于返回一个局部对象的话,这样必定会产生拷贝 在面对较大的拷贝时候,我们可以用std::move()函数显式的将局部对象转换成右值。 */ /************************************************************************/ Valueo(kObjectType); { Valuecontacts(kArrayType); //adding elements to contacts array. o.AddMember("contacts",contacts,document.GetAllocator()); //给Object添加成员 } /************************************************************************/ /* String */ /************************************************************************/ Value v; v.SetString("hello");//静态创建文本.默认调用strlen获得字符串长度 char buffer[10] ={0}; size_tlen = sprintf(buffer,"%s","hello");//动态文本 v.SetString(buffer,len); //于是乎我们可以动态的创建一个document成员 document.AddMember(v,"啦啦啦啦啦啦啦",document.GetAllocator()); /************************************************************************/ /* 我需要深度拷贝 不能用=操作符,我如何拷贝? */ /************************************************************************/ { Documentd; Document::AllocatorType&a = d.GetAllocator(); Valuev1("foo"); //Value v2(v1); // not allowed Value v2(v1,a); //构造拷贝 assert(v1.IsString()); // v1 untouched d.SetArray().PushBack(v1,a).PushBack(v2,a); // 右值语意 assert(v1.IsNull()&& v2.IsNull()); v2.CopyFrom(d,a); // 构造拷贝第二种方法 assert(d.IsArray()&& d.Size() == 2); // d untouched v1.SetObject().AddMember("array",v2,a);//右值语意 d.PushBack(v1,a);//右值语意 assert(v1.IsNull()&& v2.IsNull()); } /************************************************************************/ /* 交换值*/ /************************************************************************/ { Valueaa(123); Valuebb("Hello"); aa.Swap(bb); assert(aa.IsString()); assert(bb.IsInt()); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |