jsoncpp的使用

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();
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值