C++ json库,C++json
JSON(JavaScript对象符号)跟可扩展标记语言一样也是一种数据交换格式,了解数据请参考其官网http://json.org/,本文不再对数据做介绍,将重点介绍c的数据解析库的使用方法100 .数据官网上列出了各种语言对应的数据解析库,作者仅介绍自己使用过的两种C的数据解析库:jsoncpp(v0.5.0)和增强版(1.34.0版).
一。使用jsoncpp解析数据
Jsoncpp是个跨平台的开源库,首先从http://jsoncpp.sourceforge.net/上下载jsoncpp库源码,我下载的是v0.5.0,压缩包大约107K,解压,在JSON CPP-src-0。5 .0/makefiles/vs71目录里找到jsoncpp.sln,用VS2003及以上版本编译,默认生成静态链接库。在工程中引用,只需要包含/json及。解放运动文件即可。
使用JsonCpp前先来熟悉几个主要的类:
Json:值可以表示里所有的类型,比如整型,字符串,对象,数组等,具体应用将会在后边示例中介绍。
Json:阅读器将数据文件流或字符串解析到Json:Value,主要函数有解析。
Json:Writer与Json:阅读器相反,将Json:值转化成字符串流,注意它的两个子类:Json:FastWriter和Json:StyleWriter,分别输出不带格式的数据和带格式的json。
1.从字符串解析数据
{
const char * str= { upload id : up 000000 , code:100, msg : , files : } ;
JSON:reader reader;
JSON:value root;
if(reader.parse(str,root))//reader将数据字符串解析到根,根将包含数据里所有子元素
{
STD:string upload _ id=root[ upload id ].asString();//访问节点,upload_id=UP00000
intcode=root[code].asInt();//访问节点,代码=100
}
返回0
}
int ParseJsonFromString()
const char * str= { upload id : up 000000 , code: 100, msg : , files : } ;
JSON:Reader Reader;
JSON:Value root;
if (reader.parse(str,root)) //reader将数据字符串解析到根,根将包含数据里所有子元素
STD:string upload _ id=root[ upload id ].asString();//访问节点,upload_id=UP00000
int code=root[code].asInt();//访问节点,代码=100
返回0;
}
2.从文件解析数据
数据文件内容:
JSON:reader reader;
//Json:Value是一种很重要的类型,可以代表任意类型。如整型,字符串,对象,数组.
JSON:value root;
STD:如果流为;
is.open(文件名,STD:IOs:binary);
if(reader.parse(is,root))
{
STD:字符串代码;
如果(!根[文件]。isNull())//访问节点,Accessanobjectvaluebyname,createanullmemberrifitdoesnotexist .
code=root[uploadid].asString();
//访问节点,returnthemembernamedkeyiftexist,defaultValueotherwise否则否则。
code=root.get(uploadid , null ).asString();
//得到文件的数组个数
intfile_size=root[files].size();
//遍历数组
for(inti=0;我文件大小;我)
{
JSON:value val _ image=root[ files ][I][ images ];
内膜大小=val _ image。size();
for(intj=0;j image _ sizej)
{
STD:string type=val _ image[j][ type ].asString();
STD:string URL=val _ image[j][ URL ].asString();
}
}
}
是。close();
返回0
}
int ParseJsonFromFile(const char * filename)
//解析数据用Json:阅读器
JSON:Reader Reader;
//Json:Value是一种很重要的类型,可以代表任意类型。如整型,字符串,对象,数组.
JSON:Value root;
std:ifstream为;
is.open(文件名,STD:IOs:binary);
if (reader.parse(is,root))
标准:字符串代码;
如果(!根[文件]。isNull()) //访问节点通过名称访问对象值,如果不存在,则创建一个空成员。
code=root[uploadid].asString();
//访问节点,如果存在,则返回成员命名键,否则返回默认值.
code=root.get(uploadid , null ).asString();
//得到文件的数组个数
int file_size=root[files].size();
//遍历数组
for(int I=0;我文件大小;我)
JSON:Value val _ image=root[ files ][I][ images ];
int image _ size=val _ image。size();
for(int j=0;j image _ sizej)
STD:string type=val _ image[j][ type ].asString();
STD:string URL=val _ image[j][ URL ].asString();
是。close();
返回0;
}
3.在数据结构中插入数据
JSON:ValuearrayObj;//构建对象
Json:值新项目,新项目1
new _ item[ date ]= 2011-12-28 ;
new _ item 1[ time ]= 22:30:36 ;
数组对象。append(new _ item);//插入数组成员
数组对象。追加(new _ item 1);//插入数组成员
intfile_size=root[files].size();
for(inti=0;我文件大小;我)
root[ files ][I][ exifs ]=array obj;//插入原数据中
JSON:Value数组obj//构建对象
Json:Value new_item,new _ item 1;
new _ item[ date ]= 2011-12-28 ;
new _ item 1[ time ]= 22:30:36 ;
数组对象。append(new _ item);//插入数组成员
数组对象。追加(new _ item 1);//插入数组成员
int file_size=root[files].size();
for(int I=0;我文件大小;我)
root[ files ][I][ exifs ]=array obj;//插入原数据中
4.输出数据
//转换为字符串(带格式)
STD:string out=root。tostyledstring();
//输出无格式数据字符串
JSON:快手写手;
STD:string out 2=writer。写(根);
//转换为字符串(带格式)
STD:string out=root。tostyledstring();
//输出无格式数据字符串
Json:FastWriter作家;
STD:string out 2=writer。写(根);
二。使用促进属性树解析数据
属性树可以解析xml,json,ini,info等格式的数据,用属性树解析这几种格式使用方法很相似。
解析数据很简单,命名空间为升压:属性_树,reson_json函数将文件流、字符串解析到ptree,write_json将ptree输出为字符串或文件流。其余的都是对ptree的操作。
解析数据需要加头文件:
#包含boost/property_tree/ptree.hpp
#包含boost/property _ tree/JSON _ parser。HPP
1.解析数据
解析一段下面的数据:
{
URL : fmn 057/2011 12 21/1130/head _ kJoO _ 05d 9000251 de 125 c . jpg
},
{
URL : fmn 057/2011 12 21/1130/original _ kJoO _ 05d 9000251 de 125 c . jpg
}
]
}
{
代码:0,
图像:
URL : fmn 057/2011 12 21/1130/head _ kJoO _ 05d 9000251 de 125 c . jpg
URL : fmn 057/2011 12 21/1130/original _ kJoO _ 05d 9000251 de 125 c . jpg
}
{
std:stringstr={code:0, images :[{ URL : fmn 057/2011 12 21/1130/head _ kJoO _ 05d 9000251 de 125 c . jpg },{ URL : fmn 057/2011 12 21/1130/original _ kJoO _ 05d 9000251 de 125 c . jpg }];
使用命名空间boost:property _ tree;
STD:string streams(str);
ptreept
尝试{
read_json(ss,pt);
}
catch(ptree_error e){
返回1
}
尝试{
int code=pt。get int( code );//得到代码的价值
ptreeimage _ array=pt。get _ child( images );//get_child得到数组对象
//遍历数组
BOOST _ FOREACH(BOOST:property _ tree:ptree:value _ type v,image_array)
{
STD:字符串流;
write_json(s,v . second);
STD:string image _ item=s . str();
}
}
catch(ptree_error e)
{
返回2
}
返回0
}
int ParseJson()
std:string str={code:0, images :[{ URL : fmn 057/2011 12 21/1130/head _ kJoO _ 05d 9000251 de 125 c . jpg },{ URL : fmn 057/2011 12 21/1130/original _ kJoO _ 05d 900251 de 125 c . jpg }];
使用命名空间boost:property _ tree;
STD:字符串流ss(str);
ptree角;
尝试{
read_json(ss,pt);
catch(ptree_error e) {
返回1;
尝试{
int code=pt。get int( code );//得到代码的价值
ptree image _ array=pt。get _ child( images );//get_child得到数组对象
//遍历数组
BOOST _ FOREACH(BOOST:property _ tree:ptree:value _ type v,image_array)
STD:字符串流s;
write_json(s,v . second);
STD:string image _ item=s . str();
catch (ptree_error e)
return 2;
返回0;
}
2.构造数据
{
std:stringstr={code:0, images :[{ URL : fmn 057/2011 12 21/1130/head _ kJoO _ 05d 9000251 de 125 c . jpg },{ URL : fmn 057/2011 12 21/1130/original _ kJoO _ 05d 9000251 de 125 c . jpg }];
使用命名空间boost:property _ tree;
STD:string streams(str);
ptreept
尝试{
read_json(ss,pt);
}
catch(ptree_error e){
返回1
}
//修改/增加一个键值,键不存在则增加
pt.put(upid , 00001 );
//插入一个数组
ptreeexif _ array
ptreearray1,array2,array3
array1.put(Make , NIKON );
array2.put(DateTime , 2011:05:3106:47:09 );
array3.put(软件, 1.01版);
EXIF阵列。push _ back(STD:make _ pair( ,数组1));
EXIF阵列。push _ back(STD:make _ pair( ,array 2));
EXIF阵列。push _ back(STD:make _ pair( ,数组3));
//EXIF _数组。push _ back(STD:Make _ pair( Make , NIKON );
//EXIF _数组。push _ back(STD:make _ pair( DateTime , 2011:05:3106:47:09 );
//EXIF _数组。push _ back(STD:make _ pair(软件, 1.01版);
pt.put_child(exifs ,EXIF _ array);
STD:字符串流2;
write_json(s2,pt);
stringoutstr=S2。str();
返回0
}
int InsertJson()
std:string str={code:0, images :[{ URL : fmn 057/2011 12 21/1130/head _ kJoO _ 05d 9000251 de 125 c . jpg },{ URL : fmn 057/2011 12 21/1130/original _ kJoO _ 05d 900251 de 125 c . jpg }];
使用命名空间boost:property _ tree;
STD:字符串流ss(str);
ptree角;
尝试{
read_json(ss,pt);
catch(ptree_error e) {
返回1;
//修改/增加一个键值,键不存在则增加
pt.put(upid , 00001 );
//插入一个数组
ptree exif _ array
ptree数组1,数组2,数组3;
array1.put(Make , NIKON );
array2.put(DateTime , 2011:05:31 06:47:09 );
array3.put(软件, 1.01版);
EXIF阵列。push _ back(STD:make _ pair( ,数组1));
EXIF阵列。push _ back(STD:make _ pair( ,array 2));
EXIF阵列。push _ back(STD:make _ pair( ,数组3));
//EXIF _数组。push _ back(STD:Make _ pair( Make , NIKON );
//EXIF _数组。push _ back(STD:make _ pair( DateTime , 2011:05:31 06:47:09 );
//EXIF _数组。push _ back(STD:make _ pair(软件, 1.01版);
pt.put_child(exifs ,EXIF _ array);
STD:字符串流S2;
write_json(s2,pt);
string out str=S2。str();
返回0;
}
三。两种解析库的使用经验
1.用升压:属性树解析字符串遇到\/时解析失败,而jsoncpp可以解析成功,要知道/前面加一个\是数据标准格式。
2 .升压:属性树的read_json和write_json在多线程中使用会引起崩溃。
针对1,可以在使用升压:属性树解析前写个函数去掉\/中的\,针对2,在多线程中同步一下可以解决。
我的使用心得:使用升压:属性树不仅可以解析json,还可以解析xml,信息等格式的数据。对于解析json,使用升压:属性树解析还可以忍受,但解析xml,由于遇到问题太多只能换其它库了。
来自:http://博客。csdn。net/Hz Yong _ c/article/details/7163589
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。