jsoncpp安装
- 安装 scons
sudo apt-get install scons
- 安装 jsoncpp
官网下载jsoncpp的源码包,执行以下命令:
tar -zxf jsoncpp-src-0.5.0.tar.gz
cd jsoncpp-src-0.5.0
scons platform=linux-gcc
cp libs/linux-gcc-4.1.2/libjson_linux-gcc-4.1.2_libmt.so /lib
cp include/json/ /usr/include
- pro文件配置
LIBS += /lib/libjson_linux-gcc-4.8_libmt.so
INCLUDEPATH += /usr/include/
jsoncpp示例
/*
{
"name":"HJ",
"age":25
}*/
#include "jsoncpp/json.h"
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
ifstream ifs;
ifs.open("testjson.json");
assert(ifs.is_open());
Json::Reader reader;
Json::Value root;
if (!reader.parse(ifs, root, false))
{
return -1;
}
std::string name = root["name"].asString();
int age = root["age"].asInt();
std::cout << name << std::endl;
std::cout << age << std::endl;
return 0;
}
//[{"name" : "xiaoy", "age" :17} , {"name" : "xiaot", "age" : 20}]
#include "jsoncpp/json.h"
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
ifstream ifs;
ifs.open("testjson.json");
assert(ifs.is_open());
Json::Reader reader;
Json::Value root;
if (!reader.parse(ifs, root, false))
{
return -1;
}
std::string name;
int age;
int size = root.size();
for (int i=0; i<size; ++i)
{
name = root[i]["name"].asString();
age = root[i]["age"].asInt();
std::cout<< name <<" "<< age <<std::endl;
}
return 0;
}
//[{"age":100,"name":"hello world"}]
#include "jsoncpp/json.h"
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
Json::Value root;
Json::FastWriter writer;
Json::Value person;
person["name"] = "hello world";
person["age"] = 100;
root.append(person);
std::string json_file = writer.write(root);
ofstream ofs;
ofs.open("test1.json");
assert(ofs.is_open());
ofs << json_file;
return 0;
}
#include "jsoncpp/json.h"
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
Json::Value iJsValue[2];
Json::FastWriter iJsWriter;
std::string iCmdStr = "!message:";
iJsValue[0]["name"] = "HJ";
iJsValue[0]["age"] = "25";
iJsValue[1]["Parameter"]["Height"]= "120";
iJsValue[1]["Parameter"]["Weight"]= "24";
iCmdStr.append(iJsWriter.write(iJsValue[0]));
std::cout << iCmdStr;
iCmdStr = "!message:";
iCmdStr.append(iJsWriter.write(iJsValue[1]));
std::cout << iCmdStr;
Json::Reader reader;
Json::Value value;
std::string strValue = "{\"key1\":\"value1\","
"\"array\":[{\"key2\":\"value2\"},{\"key2\":\"value3\"},{\"key2\":\"value4\"}]}";
if(reader.parse(strValue,value))
{
string out = value["key1"].asString();
std:cout << out << std::endl;
const Json::Value arrayObj = value["array"];
for (int i=0; i<arrayObj.size(); i++)
{
out = arrayObj[i]["key2"].asString();
std::cout << out;
if(i != arrayObj.size() - 1)
std::cout << std::endl;
}
}
return 0;
}
//[{"x":100,"y":20,"z":300}]
void SaveLocation(vector<float> fMoroPos, vector<float> fTripodPose)
{
Json::Value root;
Json::FastWriter writer;
Json::Value locinfo;
fMoroPos.resize(3);
fMoroPos[0] = 100;
fMoroPos[1] = 20;
fMoroPos[2] = 300;
locinfo["x"] = fMoroPos[0];
locinfo["y"] = fMoroPos[1];
locinfo["z"] = fMoroPos[2];
root.append(locinfo);
std::string json_file = writer.write(root);
ofstream ofs;
ofs.open("locinfo.json");
assert(ofs.is_open());
ofs << json_file;
}
void SetLocation()
{
ifstream ifs;
ifs.open("locinfo.json");
assert(ifs.is_open());
Json::Reader reader;
Json::Value root;
if (!reader.parse(ifs, root, false))
{
return;
}
float fx = root[0]["x"].asInt();
float fy = root[0]["y"].asInt();
float fz = root[0]["z"].asInt();
std::cout << "f " << fx << fy << fz <<std::endl;
}
jsoncpp流解析
使用Json字符串解析数据非常方便,但是遇到同时要传输其他非Json字符串数据时,需要进行处理。处理方式如下,定义两种数据格式:
Json字符串格式 !message:{key:value}
非Json字符串格式 ?message:{file}
通过判断帧头确定是否为Json字符串
void RecvProc(eint pArgv)
{
int nRecvLen=0;
uint8 bRecvBuf[1500]={0};
Json::Reader iJsReader;
Json::Value iJsValue;
std::string iJsonStr;
std::string strTmp;
bool bJsValue = false;
bool bisJsValue = true;
const char cIJson = '!';//Json字符串头
const char cNJson = '?';//非Json字符串头
const char cTail = '}';//尾
int nCnt = 0;
FILE* fp = fopen("baymax","w+");
while(1)
{
nRecvLen = recv(bRecvBuf,1500);
for(uint n=0; n<nRecvLen; n++)
{
if(cIJson == bRecvBuf[n])
{
bisJsValue = true;
strTmp.clear();
}
else if(cNJson == bRecvBuf[n])
{
bisJsValue = false;
nCnt = 0;
}
else if(cTail == bRecvBuf[n])
{
strTmp += bRecvBuf[n];
nCnt++;
if(bisJsValue)
{
//std::cout << "***Json:**** "<< strTmp << std::endl;
iJsonStr = (echar*)(&strTmp[0] + strlen("message:"));
//std::cout << "iJsonStr:" << iJsonStr << std::endl;
try
{
bJsValue = iJsReader.parse(iJsonStr, iJsValue);
}
catch(...)
{
std::cout << "Json error!!!!!!!!" << std::endl;
return ;
}
//here add Json Analysis eg:iJsValue["Command"].asString()
strTmp.clear();
}
else
{
//std::cout << "***NJson:**** "<< strTmp << std::endl;
fclose(fp);
nCnt = 0;
}
}
else
{
if(bisJsValue)
strTmp += bRecvBuf[n];//如果是Json字符串则存入string
else
{
nCnt++;//如果不是Json字符串则读一个存一个(若文件比较小亦可以存入string)
//strTmp += bRecvBuf[n];
//if((strTmp.length() > strlen("message:{"))&&(bRecvBuf[n]!=NULL))
if((nCnt > strlen("message:{"))&&(bRecvBuf[n]!=NULL))
{
fwrite(&bRecvBuf[n],sizeof(char),1,fp);
}
}
}
}
memset(bRecvBuf, 0 ,sizeof(bRecvBuf));
}
}
- 调试遇到的错误1:char给string赋值
int main(int argc, char *argv[])
{
std::string str;
char buf[100]={"1,2,3,4,5,6"};
str[0] = buf[0];
cout << str[0] << endl;//打印1
cout << str.c_str() << endl;//打印1
cout << str << endl;//打印空(不能直接用)
str = buf;
cout << str[0] << endl;//打印1
cout << str << endl;//打印1,2,3,4,5,6
str += buf[0];
cout << str << endl;//打印1
str.append((char*)&buf[0]);
cout << str << endl;//打印1,2,3,4,5,6
return 0;
}
/*注:string类型数据通过字符数组赋值时(如strTmp[nCnt] = bRecvBuf[n]),不能直接引用string的值(其值为空)。\
如真的需要该功能应该使用string的+操作符!如这里可用str+=buf[0];\
如果用append方法就将整个buf添加进去了!*/
- 调试遇到的错误2:粘包现象
Json字符串数据发送太快导致粘包现象,使得无法正确解析。
在解析TCP传输的json字符串时,可能会出现粘包的现象导致json的解析方式出现错误,解析时通过\n
分离一帧json字符串即可解决该问题,上代码。
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
string str = "{\"objhei\":0,\"objn\":0,\"objwid\":0,\"objx\":44,\"objy\":0}\ {\"objhei\":0,\"objn\":0,\"objwid\":0,\"objx\":6789,\"objy\":0}\n{\"objhei\":0,\"objn\":0,\"objwid\":0,\"objx\":34,\"objy\":0}\n{\"objhei\":0,\"objn\":0,\"objwid\":0,\"objx\":34,\"objy\":0}\n";
cout << str << endl << "*****" << endl;
int i = 0;
int spos = 0;
int epos = 0;
string tmp;
while(i < str.length())
{
if(str[i]=='\n')
{
epos = i+1;
tmp = str.substr(spos,epos-spos);//(start pos,length)
cout << tmp << epos - spos << endl;
spos = epos;
}
i++;
}
return 0;
}
- 调试遇到的错误3:在解析json字符串时,先查找是否有该键,再取键值
bool isNull() const;
bool isBool() const;
bool isInt() const;
bool isUInt() const;
bool isIntegral() const;
bool isDouble() const;
bool isNumeric() const;
bool isString() const;
bool isArray() const;
bool isObject() const;
if(json["staus"].isString()){
string temp = json["staus"].asCString();
}