jSON(JavaScript Object Notation)是一种轻量级的数据交换格式.易于阅读和理解,也易于机器解析和生成.
JSON构建于两种结构:
- "名称/值"对的集合(A collection of name/value pairs).在不同的语言中被理解为对象(Object),记录(Records),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者是关联数组(associative array)
- 值得有序列表(An ordered list of values),在大部分语言中被理解为数据(array)
JSON的形式
- 对象
对象是一个无序的"'名称/值'对"集合.一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。
2.数组
数组是值(value)的有序集合。一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间间使用“,”(逗号)分隔
字符串一定要用双引号括起来
数组中可以嵌套数组和对象
{
"name": "BeJson", "url": "http://www.bejson.com", "page": 88, "isNonProfit": true, "address": { "street": "科技园路.", "city": "江苏苏州", "country": "中国" }, "links": [ { "name": "Google", "url": "http://www.google.com" }, { "name": "Baidu", "url": "http://www.baidu.com" }, { "name": "SoSo", "url": "http://www.SoSo.com" } ]
}
解析json的工具办法:使用第三方jsoncpp
1.直接网上下载:
参考C++中使用JsonCpp - 简书。这个参考是是从git下载,用python 实现的,我没有python。
使用该链接: https://pan.baidu.com/s/1dSf7154_fuudvt_OYe4IZg 提取码: i3pu
或者是找到旧版直接用vs编译出静态链接库即 json-cpp - Browse /jsoncpp/0.6.0-rc2 at SourceForge.net 选中下载jsoncpp-src-0.6.0-rc2
2.安装、配置、测试过程
a.编译出一个静态链接库.lib 在这里会生成json_vc71_libmtd.lib
b.测试,建一个新工程,引入jsoncpp的头文件、库文件
c.更换MTD工程->属性->配置属性->c/c+±>代码生成->运行库,设置运行库为多线程调试 (/MTd)
具体可参考VS2015配置jsoncpp详解_hpuzsk的博客-CSDN博客_jsoncpp vs2015
另外的一种办法.在vs2017中通过NuGet直接安装jsoncpp到项目下(该方法不成功,编译出现很多bug)
在浏览中输入jsoncpp,选中jsoncpp下载。会在项目下有个package包,这个包下面就是jsoncpp库。
如
搜索安装过程如下
正在尝试收集与目标为“native,Version=v0.0”的项目“stdtest”有关的包“jsoncpp.0.6.0.1”的依赖项信息
收集依赖项信息花费时间 366.22 ms
正在尝试解析程序包“jsoncpp.0.6.0.1”的依赖项,DependencyBehavior 为“Lowest”
解析依赖项信息花费时间 0 ms
正在解析操作以安装程序包“jsoncpp.0.6.0.1”
已解析操作以安装程序包“jsoncpp.0.6.0.1”
从“nuget.org”检索包“jsoncpp 0.6.0.1”
从“nuget.org”检索包“jsoncpp.redist 0.6.0.1”
GET https://api.nuget.org/v3-flatcontainer/jsoncpp.redist/0.6.0.1/jsoncpp.redist.0.6.0.1.nupkg
GET https://api.nuget.org/v3-flatcontainer/jsoncpp/0.6.0.1/jsoncpp.0.6.0.1.nupkg
OK https://api.nuget.org/v3-flatcontainer/jsoncpp.redist/0.6.0.1/jsoncpp.redist.0.6.0.1.nupkg 863 毫秒
OK https://api.nuget.org/v3-flatcontainer/jsoncpp/0.6.0.1/jsoncpp.0.6.0.1.nupkg 916 毫秒
正在安装 jsoncpp.redist 0.6.0.1。
正在安装 jsoncpp 0.6.0.1。
正在将程序包“jsoncpp.redist.0.6.0.1”添加到文件夹“F:\test\stdtest\packages”
已将程序包“jsoncpp.redist.0.6.0.1”添加到文件夹“F:\test\stdtest\packages”
已将程序包“jsoncpp.redist.0.6.0.1”添加到“packages.config”
已将“jsoncpp.redist 0.6.0.1”成功安装到 stdtest
正在将程序包“jsoncpp.0.6.0.1”添加到文件夹“F:\test\stdtest\packages”
已将程序包“jsoncpp.0.6.0.1”添加到文件夹“F:\test\stdtest\packages”
已将程序包“jsoncpp.0.6.0.1”添加到“packages.config”
已将“jsoncpp 0.6.0.1”成功安装到 stdtest
执行 nuget 操作花费时间 5.41 sec
已用时间: 00:00:06.0361098
这种方法(我并没有成功,一堆字link error)。
另外第三种方法:其实这种方法就是第一种,只是生成的lib文件名字改了一下。同时下面的这个参考的没有.project文件,不适用于vs软件。最好还是第一种办法好。
可参考:windows C++ vs任何版本 jsoncpp配置教程_THE XING-CSDN博客
测试的例子:
json Value的新建及key的访问
cout << "json Value的新建及key的访问" << endl;
// 新建Json::Value对象
Json::Value value1;
// 给字段赋值,key必须为string型
// 类似STL的map,访问一个不存在的字段时会自动新建一个字段
value1["name"] = "英语"; // string型
Json::Value value2;
value2["name"] = "语文"; // string型
value2["score"] = 80; // 整型
value2["right"] = true; // bool型
value2["percent"] = 12.34567890; // double型
value2["count"]; // 单纯的访问一个key,由于该key不存在,所以会新建,值的类型为Json::nullValue
// 新建Value对象
Json::Value valueArr;
valueArr["name"] = "json array"; // string型
valueArr["object"] = value1; // json::Value型
valueArr["array"].append("array_element_one"); // 访问key为"array",该key不存在,会新建,类型为Json::arrayValue,数组型,且把第一个元素赋值为string型"array element one"
valueArr["array"].append("array_element_two"); // 该key已存在,往后面增加元素,赋值为string型"array element two"
valueArr["array"].append(33333); // 该key已存在,往后面增加元素,赋值为整型33333
valueArr["array"].append(value2); // 该key已存在,往后面增加元素,赋值为json::Value型
// 计算其中字段的个数
cout << "size = " << valueArr.size() << endl;
// key的访问
// 访问字段"object"的值,访问一个key前,先预判是否有该key
if (valueArr.isMember("object"))
{
// 存在的话,再判断其value的类型是否是自己预期的,根据前面32行赋值代码可知:"object"的值是Json::Value类型
if (valueArr["object"].isObject())
{
// 转换成对应的类型
Json::Value object = valueArr["object"];
// 字段检测,取值,可以放在一行中,谨记:先检测是否存在,后判断类型
if (object.isMember("name") && object["name"].isString())
{
string name = object["name"].asString();
cout << "valueArr[object] key = name, value = " << name.c_str() << endl;
}
}
}
// 访问字段"array"的值
if (valueArr.isMember("array") && valueArr["array"].isArray()) // 根据前面33行赋值代码可知:"object"的值是Json::arrayValue类型的
{
// 注意:虽然类型为Json::arrayValue,也是转换为Json::Value类型的
Json::Value arrayObject = valueArr["array"];
// 得到其元素个数
int array_size = arrayObject.size();
// 根据类型,逐个输出元素
for (int i = 0; i<array_size; i++)
{
// 若是Json::Value型
if (arrayObject[i].isObject())
{
// 转换成对应的类型
Json::Value object = arrayObject[i];
// 字段检测,取值
if (object.isMember("score") && object["score"].isInt())
{
int score = object["score"].asInt();
cout << "valueArr[array][" << i << "]" << " key = score, value = " << score << endl;
}
// 字段检测,取值
if (object.isMember("percent") && object["percent"].isDouble())
{
double percent = object["percent"].asDouble();
cout << "valueArr[array][" << i << "]" << " key = percent, value = " << percent << endl;
}
}
// 若是string类型
if (arrayObject[i].isString())
{
cout << "valueArr[array][" << i << "] value is " << arrayObject[i].asString() << endl;
}
// 若是整型
if (arrayObject[i].isInt())
{
cout << "valueArr[array][" << i << "] value is " << arrayObject[i].asInt() << endl;
}
}
}
cout << "\n\n" << endl;
从字符串中解析出json::Value
cout << "从字符串中解析出json::Value" << endl;
// 要解析的json字符串
std::string strValue = "{\"key1\":\"value1\",\"array\":[{\"key2\":\"value2\"},{\"key2\":999},{\"key2\":\"value4\"}]}";
// json对象
Json::Value value3;
// 开始解析json,解析后的json对象存储在value中,成功返回true
Json::Reader reader;
if (reader.parse(strValue, value3))
{
// 字段key1
if (value3.isMember("key1") && value3["key1"].isString())
{
cout << "value3[key1] = " << value3["key1"].asString() << endl;
}
// 字段array
if (value3.isMember("array") && value3["array"].isArray())
{
Json::Value valueArray = value3["array"];
for (int i = 0; i<valueArray.size(); i++)
{
if (valueArray[i].isObject() && valueArray[i].isMember("key2") && valueArray[i]["key2"].isString())
{
cout << "value3[array][" << i << "].[key2] = " << valueArray[i]["key2"].asString() << endl;
}
if (valueArray[i].isObject() && valueArray[i].isMember("key2") && valueArray[i]["key2"].isInt())
{
cout << "value3[array][" << i << "].[key2] = " << valueArray[i]["key2"].asInt() << endl;
}
}
}
}
cout << "\n\n" << endl;
把json::Value写入到文件中
cout << "把json::Value写入到文件中" << endl;
ofstream ofs;
ofs.open("test.json");
// 第一种办法:直接输出,带缩进,效果等同于第三种办法
//ofs << valueArr.toStyledString();
// 第二种办法:快速输出,没有格式
//Json::FastWriter fw;
//ofs<<fw.write(valueArr)<<endl;
// 第三种办法:缩进输出
Json::StyledWriter sw;
ofs << sw.write(valueArr) << endl;
ofs.close();
cout << "输出到文件完毕" << endl;
cout << "\n\n" << endl;
写入文件后,test.json文件内容如下
{
"array" : [
"array_element_one",
"array_element_two",
33333,
{
"count" : null,
"name" : "语文",
"percent" : 12.34567890,
"right" : true,
"score" : 80
}
],
"name" : "json array",
"object" : {
"name" : "英语"
}
}
从文件中读取json::Value //
cout << "从文件中读取到json:value" << endl;
ifstream ifs;
ifs.open("test.json");
Json::Value value4;
Json::Reader jsonReader;
if (jsonReader.parse(ifs, value4))
{
// 得到字段的个数
cout << "size = " << value4.size() << endl;
// 访问
if (valueArr.isMember("name") && valueArr["name"].isString())
{
cout << "valueArr[name] = " << valueArr["name"].asString() << endl;
}
}