json文件参考链接
JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
json与其他存储数据方式比较
为什么要用json文件呢?
我们最常使用的存储数据的方式有很多,比如利用txt文件存,利用xml存,利用word存,利用Excel存,如果我们要求比较高,还可以使用数据库存。
相对于txt,word来说,json格式更加明确,获取重要信息非常方便。
相对于xml来说,json格式更加简洁,存储同样的文件,花费的内存更小。
相对于Excel来说,json更适合存储字符类文件。Excel相当于比较简单的数据库了。
相对于数据库来说,json更加方便,数据库我们还需要做一些设置,安装一些软件。json可以直接使用。
C++从文件中读取json
以下面这个json文件为例:
{
"age" : 21,
"friends" : {
"friend_age" : 21,
"friend_name" : "ZhaoWuxian",
"friend_sex" : "man"
},
"hobby" : [ "sing", "run", "Tai Chi" ],
"name" : "shuiyixin",
"sex" : "man"
}
读取代码如下:
void readFileJson()
{
Json::Reader reader;
Json::Value root;
//从文件中读取,保证当前文件有demo.json文件
ifstream in("demo.json", ios::binary);
if (!in.is_open())
{
cout << "Error opening file\n";
return;
}
if (reader.parse(in, root))
{
//读取根节点信息
string name = root["name"].asString();
int age = root["age"].asInt();
string sex = root["sex"].asString();
cout << "My name is " << name << endl;
cout << "I'm " << age << " years old" << endl;
cout << "I'm a " << sex << endl;
//读取子节点信息
string friend_name = root["friends"]["friend_name"].asString();
int friend_age = root["friends"]["friend_age"].asInt();
string friend_sex = root["friends"]["friend_sex"].asString();
cout << "My friend's name is " << friend_name << endl;
cout << "My friend's sex is "<<friend_sex << endl;
cout << "My friend is " << friend_age << " years old" << endl;
//读取数组信息
cout << "Here's my hobby:" << endl;
for (unsigned int i = 0; i < root["hobby"].size(); i++)
{
string ach = root["hobby"][i].asString();
cout << ach << '\t';
}
cout << endl;
cout << "Reading Complete!" << endl;
}
else
{
cout << "parse error\n" << endl;
}
in.close();
}
注意读取子节点信息的形式
以下面这个json文件为例:
{
"order" : 0,
"robot_pose" : {
"ori_w" : 0.99997542567563957,
"ori_x" : 0,
"ori_y" : 0,
"ori_z" : 0.0070105666549410434,
"pos_x" : -0.0090275746583154473,
"pos_y" : 0.01617900456888452,
"pos_z" : 0
}
}
读取代码
Json::Reader reader_;
Json::Value root_;
std::ifstream in_;
vector<double> goal_point(6,0);
double pos_x,pos_y,pos_z,ori_x,ori_y,ori_z,ori_w;
in_.open( "/home/ubuntu/myagv_ros/src/auto_dock/data/1.json",std::ios::binary);
if (!in_.is_open())
{
std::cout << "Error opening file\n" << std::endl;
}
else if (reader_.parse(in_, root_))
{
goal_point[0] = root_["robot_pose"]["pos_x"].asDouble();
goal_point[1] = root_["robot_pose"]["pos_y"].asDouble();
goal_point[2] = root_["robot_pose"]["pos_z"].asDouble();
goal_point[3] = root_["robot_pose"]["ori_x"].asDouble();
goal_point[4] = root_["robot_pose"]["ori_y"].asDouble();
goal_point[5] = root_["robot_pose"]["ori_z"].asDouble();
goal_point[6] = root_["robot_pose"]["ori_w"].asDouble();
}
cout的时候double默认显示6位,可以用以下代码改为16位
cout<<fixed;
cout.precision(16);
C++写入json文件
json文件如下:
{
"age" : 21,
"friends" : {
"friend_age" : 21,
"friend_name" : "ZhaoWuxian",
"friend_sex" : "man"
},
"hobby" : [ "sing", "run", "Tai Chi" ],
"name" : "shuiyixin",
"sex" : "man"
}
写入代码如下:
void writeFileJson()
{
//根节点
Json::Value root;
//根节点属性
root["name"] = Json::Value("shuiyixin");
root["age"] = Json::Value(21);
root["sex"] = Json::Value("man");
//子节点
Json::Value friends;
//子节点属性
friends["friend_name"] = Json::Value("ZhaoWuxian");
friends["friend_age"] = Json::Value(21);
friends["friend_sex"] = Json::Value("man");
//子节点挂到根节点上
root["friends"] = Json::Value(friends);
//数组形式
root["hobby"].append("sing");
root["hobby"].append("run");
root["hobby"].append("Tai Chi");
//直接输出
//cout << "FastWriter:" << endl;
//Json::FastWriter fw;
//cout << fw.write(root) << endl << endl;
//缩进输出
cout << "StyledWriter:" << endl;
Json::StyledWriter sw;
cout << sw.write(root) << endl << endl;
//输出到文件
ofstream os;
os.open("demo.json", std::ios::out | std::ios::app);
if (!os.is_open())
cout << "error:can not find or create the file which named \" demo.json\"." << endl;
os << sw.write(root);
os.close();
}
要注意的是:
1.如果要写入的文件不存在,会自动创建该文件;
2.如果文件存在,写入过程不会覆盖文件中原有数据,而是将新数据写在原有数据后面。
如果需要覆盖则
os.open("demo.json", std::ios::out );
void writdatajson(double x,double y,double z,double r_x,double r_y,double r_z,double r_w)
{
Json::Value root;
root["order"] = Json::Value(0);
Json::Value friend1;
friend1["pos_x"] = Json::Value(x);
friend1["pos_y"] = Json::Value(y);
friend1["pos_z"] = Json::Value(z);
friend1["ori_x"] = Json::Value(r_x);
friend1["ori_y"] = Json::Value(r_y);
friend1["ori_z"] = Json::Value(r_z);
friend1["ori_w"] = Json::Value(r_w);
root["robot_pose"]=Json::Value(friend1);
Json::StyledWriter sw;
// cout << sw.write(root) << endl << endl;
ofstream desFile("/home/ubuntu/myagv_ros/src/auto_dock/data/1.json", std::ios::out );
if (!desFile.is_open())
{
cout << "Fail to pen des.jons";
return;
}
desFile << sw.write(root);
desFile.close();
}
注意:子节点挂到根节点上方式
root["robot_pose"]=Json::Value(friend1);
ubuntu安装jsoncpp
sudo apt-get install libjsoncpp-dev
CMakeLists.txt文件
find_package(PkgConfig REQUIRED)
pkg_check_modules(JSONCPP jsoncpp)
include_directories(
include
${catkin_INCLUDE_DIRS}
${JSONCPP_LIBRARIES}
)
add_executable( openfile src/openfile.cpp)
target_link_libraries(openfile
${catkin_LIBRARIES}
${JSONCPP_LIBRARIES}
)