Json文件
参考blog:json文件格式详解
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。
示例:
{
"topics": [
{
"topic": "/RFC01",
"type": "ld_image"
},
{
"topic": "/hesai_2",
"type": "PointCloud2"
},
{
"topic": "/hesai_3",
"type": "PointCloud2"
},
{
"topic": "/ld_imugps_can",
"type": "ld_imugps_can"
},
{
"topic": "/luminar",
"type": "PointCloud2"
}
],
"points": [
{
"x_pos": 51.10718,
"y_pos": -0.716298,
"z_pos": 0.63711
},
{
"x_pos": 50.823377,
"y_pos": -0.3700837,
"z_pos": 0.63711
},
{
"x_pos": 50.78393042,
"y_pos": -1.019824088,
"z_pos": 0.63711
},
{
"x_pos": 50.44368995,
"y_pos": -0.665605186,
"z_pos": 0.63711
}
]
}
JSON建构于两种结构:
- 对象
- 对象是一个无序的“‘名称/值’”集合。
- 使用**{}**包围起来
- 值之间使用**“,”(逗号)**分隔。
- 数组
- 数组是值(value)的有序集合。
- 一个数组以**[]**包围。
- 值之间使用**“,”(逗号)**分隔。
- “Value”
值(value)可以是双引号括起来的字符串(string)、数值(number)、true、false、 null、对象(object)或者数组(array)。这些结构可以嵌套。
Json读取
参考blog:JsonCpp 的使用
Json::Value:可以表示所有支持的类型,如:int , double ,string , object, array等。其包含节点的类型判断(isNull,isBool,isInt,isArray,isMember,isValidIndex等),类型获取(type),类型转换(asInt,asString等),节点获取(get,[]),节点比较(重载<,<=,>,>=,==,!=),节点操作(compare,swap,removeMember,removeindex,append等)等函数。
Json::Reader:将文件流或字符串创解析到Json::Value中,主要使用parse函数。Json::Reader的构造函数还允许用户使用特性Features来自定义Json的严格等级。
Json::Writer:与JsonReader相反,将Json::Value转换成字符串流等,Writer类是一个纯虚类,并不能直接使用。在此我们使用 Json::Writer 的子类:Json::FastWriter(将数据写入一行,没有格式),Json::StyledWriter(按json格式化输出,易于阅读)
1.对不存在的键获取值会返回此类型的默认值。
2.通过key获取value时,要先判断value的类型,使用错误的类型获取value会导致程序中断。
3.获取json数组中某一项key的value应该使用value[arraykey][index][subkey]获取或循环遍历数组获取。
4.append函数功能是将Json::Value添加到数组末尾。
5.由于Jsoncpp解析非法json时,会自动容错成字符类型。对字符类型取下标时,会触发assert终止进程。
解决方法:启用严格模式,让非法的json解析时直接返回false,不自动容错。这样,在调用parse的时候就会返回false。
Json::Reader *pJsonParser = new Json::Reader(Json::Features::strictMode());
示例:
/* read points */
std::ifstream ifs1("path.json");
Json::Reader reader1;
Json::Value root1;
// 将ifs1中的内容解析到root1中
reader1.parse(ifs1, root1);
// points的值是数组,可以循环或迭代
int points_num = root1["points"].size();
std::cout << points_num <<std::endl;
for (int i = 0; i < points_num; ++i) {
pos_x_vec.push_back(root1["points"][i]["x_pos"].asDouble());
pos_y_vec.push_back(root1["points"][i]["y_pos"].asDouble());
pos_z_vec.push_back(root1["points"][i]["z_pos"].asDouble());
std::cout<< root1["points"][i]["x_pos"].asDouble() <<std::endl;
}
// topics的值是数组,可以循环或迭代
int topics_num = root1["topics"].size();
for (int i = 0; i < topics_num; ++i) {
topics_vec.push_back(root1["topics"][i]["topic"].asString());
std::cout<< root1["topics"][i]["topic"].asString() <<std::endl;
}
JSON文件使用迭代器遍历
object使用花括号表示的,是无序的,遍历object里的key,输出的顺序是红黑数按key的值进行排序后的顺序,与json文件显示的顺序不一样,一定要注意。
object底层是使用的map,红黑树会对key进行排序。
如果要有序遍历的话,应该使用[]的数组。需要test.