C++解析Json的方法详解【jsoncpp】
本文实例讲述了C++解析Json的方法。分享给大家供大家参考,具体如下:
JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式,和xml类似,本文主要对VS2008中使用Jsoncpp解析json的方法做一下记录。
Jsoncpp是个跨平台的开源库,下载地址:http://sourceforge.net/projects/jsoncpp/,我下载的是v0.5.0,压缩包大约104K。
方法一:使用Jsoncpp生成的lib文件
解压上面下载的Jsoncpp文件,在jsoncpp-src-0.5.0/makefiles/vs71目录里找到jsoncpp.sln,用VS2008版本编译,默认生成静态链接库。在工程中引用,只需要包含include/json下的头文件及生成的.lib文件即可。
如何包含lib文件:在.cpp文件中#pragmacomment(lib."json_vc71_libmt.lib"),在工程属性中Linker下Input中AdditionalDependencies写入lib文件名字(Release下为json_vc71_libmt.lib,Debug为json_vc71_libmtd.lib)
注意:Jsoncpp的lib工程编译选项要和VS工程中的编译选项保持一致。如lib文件工程编译选项为MT(或MTd),VS工程中也要选择MT(或MTd),否则会出现编译错误问题,debug和release下生成的lib文件名字不同,注意不要看错了,当成一个文件来使用(我就犯了这个错误)。
方法二:使用Jsoncpp包中的.cpp和.h文件
解压上面下载的Jsoncpp文件,把jsoncpp-src-0.5.0文件拷贝到工程目录下,将jsoncpp-src-0.5.0\jsoncpp-src-0.5.0\include\json和jsoncpp-src-0.5.0\jsoncpp-src-0.5.0\src\lib_json目录里的文件包含到VS工程中,在VS工程的属性C/C++下General中AdditionalIncludeDirectories包含头文件目录.\jsoncpp-src-0.5.0\include。在使用的cpp文件中包含json头文件即可,如:#include"json/json.h"。将json_reader.cpp、json_value.cpp和json_writer.cpp三个文件的PrecompiledHeader属性设置为NotUsingPrecompiledHeaders,否则编译会出现错误。
jsoncpp使用详解
jsoncpp主要包含三种类型的class:Value、Reader、Writer。jsoncpp中所有对象、类名都在namespaceJson中,包含json.h即可。
Json::Value只能处理ANSI类型的字符串,如果C++程序是用Unicode编码的,最好加一个Adapt类来适配。
下面是从网上找的代码示例:
1.从字符串解析json
constchar*str="{\"uploadid\":\"UP000000\",\"code\":100,\"msg\":\"\",\"files\":\"\"}"; Json::Readerreader; Json::Valueroot; if(reader.parse(str,root))//reader将Json字符串解析到root,root将包含Json里所有子元素 { std::stringupload_id=root["uploadid"].asString();//访问节点,upload_id="UP000000" intcode=root["code"].asInt();//访问节点,code=100 }
2.从文件解析json
intReadJsonFromFile(constchar*filename) { Json::Readerreader;//解析json用Json::Reader Json::Valueroot;//Json::Value是一种很重要的类型,可以代表任意类型。如int,string,object,array std::ifstreamis; is.open(filename,std::ios::binary); if(reader.parse(is,root,FALSE)) { std::stringcode; if(!root["files"].isNull())//访问节点,Accessanobjectvaluebyname,createanullmemberifitdoesnotexist. code=root["uploadid"].asString(); code=root.get("uploadid","null").asString();//访问节点,Returnthemembernamedkeyifitexist,defaultValueotherwise. intfile_size=root["files"].size();//得到"files"的数组个数 for(inti=0;i3.向文件中插入json
voidWriteJsonData(constchar*filename) { Json::Readerreader; Json::Valueroot;//Json::Value是一种很重要的类型,可以代表任意类型。如int,string,object,array std::ifstreamis; is.open(filename,std::ios::binary); if(reader.parse(is,root)) { Json::ValuearrayObj;//构建对象 Json::Valuenew_item,new_item1; new_item["date"]="2011-11-11"; new_item1["time"]="11:11:11"; arrayObj.append(new_item);//插入数组成员 arrayObj.append(new_item1);//插入数组成员 intfile_size=root["files"].size(); for(inti=0;i备注:Json试用不当会导致程序崩溃
Json::Valueroot; Json::Readerreader;最好作为main函数的变量,不要作为全局变量,不要多次声明(即,不要在循环或者在其他函数中声明)。因为其static属性,在第一次使用结束后会被析构,后来的使用就会访问无效地址。
json_value.cpp中
Value::~Value(){ switch(type_){ casenullValue: caseintValue: caseuintValue: caserealValue: casebooleanValue: break; casestringValue: if(allocated_) releaseStringValue(value_.string_); break; casearrayValue: caseobjectValue: deletevalue_.map_;//!!!!!! break; default: JSON_ASSERT_UNREACHABLE; }正确的使用方式如下:
intgetRebalancing(stringstr,Json::Valueroot,Json::Readerreader); intmain(){ Json::Valueroot; Json::Readerreader; while(1){ getRebalancing(string::str,root,reader); //dosomething } return0; }PS:这里再为大家推荐几款比较实用的json在线工具供大家参考使用:
在线
JSON代码检验、检验、美化、格式化工具: