使用Jsoncpp生成和解析Json字符串

       上一篇,同大家一起分享了QJson的移植(Qt4.8.3)、使用技巧(如何移植和使用QJson),本篇我们来熟悉下使用Jsoncpp生成和解析Json字符串。当然作为Qt的狂热爱好者,我还是会继续改造Jsoncpp项目,来一个Qt项目版。需要下载对应项目资源的朋友,可以在文末点击链接下载。回归到正题上来。

一、Jsoncpp下载

下载路径 https://sourceforge.net/projects/jsoncpp/

二、jsoncpp项目改造与库文件生成

我们还是先改造下项目,使jsoncpp变成我们熟悉的Qt项目,通过Qt构建和编译生成Jsoncpp.dll库文件。

1、在下载和解压jsoncpp-master源码后,我们自己定义一个jsoncpp的Qt项目目录。 先将源码中 include目录下的json文件夹 拷贝到 jsoncpp文件夹中,然后将src目录下lib_json中的所有文件拷贝到jsoncpp下的 json 文件夹中。如下图:

 

2、新建一个.pro文件,编写文件内容如下:

#-------------------------------------------------
#
# Project created by QtCreator 2017-12-09T14:36:16
#
#-------------------------------------------------

TARGET = jsoncpp

TEMPLATE = lib
CONFIG += shared
CONFIG += dll


CONFIG += exceptions

# 指定包含的头文件路径,否则对应使用<>引用的头文件会报错
INCLUDEPATH += ./

# 指定生成库的目标文件路径
DESTDIR = ./lib

#Mingw
#win32-g++{
#    BINDIR = ../win32-gcc-bin
#}

##Vs2010
#win32-msvc2010{
#    BINDIR = ../../vs2010-bin
#}

##arm-linux
#linux-arm-g++{
#    BINDIR = ../arm-linux-gcc-bin

#    DEFINES += __NO_PRECOMPILED_HEADER__
#    DEFINES += _TTY_POSIX_
#}

#CONFIG(debug, debug|release){
#    DESTDIR = $$BINDIR/debug
#}else{
#    DESTDIR = $$BINDIR/release
#}

SOURCES += \
    json/json_internalarray.inl \
    json/json_internalmap.inl \
    json/json_reader.cpp \
    json/json_value.cpp \
    json/json_valueiterator.inl \
    json/json_writer.cpp



HEADERS +=\
    json/autolink.h \
    json/config.h \
    json/features.h \
    json/forwards.h \
    json/json.h \
    json/json_batchallocator.h \
    json/reader.h \
    json/value.h \
    json/writer.h

    

3、使用Qt打开我们的jsoncpp.pro工程文件,可取消影子构建,然后构建和编译项目,在lib目录下可生成对应的.dll 和.a 库文件。

三、jsoncpp生成和解析json字符串 演示

1、首先新建一个jsoncppTest的Qt控制台项目。运行下项目。然后我们将jsoncpp.dll和.a库文件拷贝到 jsoncppTest项目的Relaese目录下。在pro文件中添加库文件链接。

#-------------------------------------------------
#
# Project created by QtCreator 2020-05-19T08:50:19
#
#-------------------------------------------------

QT       += core

QT       -= gui

INCLUDEPATH += ./json

TARGET = jsoncppTest
CONFIG   += console
CONFIG   -= app_bundle

TEMPLATE = app


SOURCES += main.cpp

LIBS += -L$$PWD/release/ -ljsoncpp

2、准备工作已经做好,接下来我们在main.cpp中进行功能测试。因为比较简单,不做过多解释,直接看代码吧。

#include <QCoreApplication>
#include "json/json.h"
#include "json/reader.h"
#include "json/value.h"
#include "json/writer.h"

#include <QString>
#include <QDebug>


// deamon以如下json的生成和解析为例,来演示jsoncpp的用法
/*
 * QString json("{"
             "\"encoding\" : \"UTF-8\","
             "\"plug-ins\" : [\"python\",\"c++\",\"ruby\"],"
             "\"types\":[{\"A\":1,\"B\":5},{\"A\":2,\"B\":6}],"
             "\"indent\" : { \"length\" : 3, \"use_space\" : true }"
             "}");
*/

QString generate_json_string(){


    Json::Value root;
    Json::Value arr_plug;
    Json::Value arr_types;
    Json::Value val;

    // 处理json对象
    // [1] encoding
    root["encoding"] = "UTF-8";

    // [2] indent
    root["indent"]["length"] = 3;
    root["indent"]["use_space"] = true;

    // 处理json数组
    // [3] plug-ins
    arr_plug.append("python");
    arr_plug.append("c++");
    arr_plug.append("ruby");

    root["plug-ins"] = arr_plug;

    // [4] types
    val["A"] = 1;
    val["B"] = 5;
    arr_types.append(val);

    val["A"] = 2;
    val["B"] = 6;
    arr_types.append(val);

    root["types"] = arr_types;

    // 生成json字符串
    Json::StyledWriter sw;
    QString string = QString::fromStdString(sw.write(root));
    return string;
}



void parsing_json_string(QString json_string){
    Json::Reader reader;
    Json::Value value;
    if(reader.parse(json_string.toStdString(),value))
    {

        /*
         * Int asInt() const;
         * UInt asUInt() const;
         * double asDouble() const;
         * bool asBool() const;
         *
         * 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;

      bool isConvertibleTo( ValueType other ) const;
        */

        /// [1] 解析json对象
        QString encoding =  QString::fromStdString(value["encoding"].asString());

        // 在转换前,可以先判断下对象的数据类型然后再做对应转换,避免出现错误
        int indent_length = value["indent"]["length"].isInt() ?  value["indent"]["length"].asInt() : 0;
        bool indent_use_sapce = value["indent"]["use_space"].asBool();


        /// [2] 解析json数组
        const Json::Value arrayObj_plug = value["plug-ins"];
        qDebug() << "plu-ins :[";
        for(unsigned int i = 0;i < arrayObj_plug.size(); ++i)
        {
            qDebug ()  << "\t"<< QString::fromStdString(arrayObj_plug[i].asString()) << ",";
        }
        qDebug() << "],";

        const Json::Value arrayObj_types = value["types"];
        qDebug() << "type: [" ;
        for(unsigned int i = 0;i < arrayObj_types.size(); ++i)
        {
            qDebug() << "{" ;
            qDebug () << "\t" << "A:" << arrayObj_types[i]["A"].asInt();
            qDebug () <<  "\t" << "B:" << arrayObj_types[i]["B"].asInt();
            qDebug() << "},";
        }
        qDebug() << "],";


        qDebug() << "encoding :" << encoding;
        qDebug() << "indent_length :" << indent_length;
        qDebug() << "indent_use_sapce :" << indent_use_sapce;
    }

}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    qDebug() << "*************************************";
    QString string = generate_json_string();
    qDebug() << generate_json_string();
    qDebug() << "*************************************";
    parsing_json_string(string);



    return a.exec();
}

打印输出结果如下:

*************************************
"{
   "encoding" : "UTF-8",
   "indent" : {
      "length" : 3,
      "use_space" : true
   },
   "plug-ins" : [ "python", "c++", "ruby" ],
   "types" : [
      {
         "A" : 1,
         "B" : 5
      },
      {
         "A" : 2,
         "B" : 6
      }
   ]
}
"
*************************************
plu-ins :[
         "python" ,
         "c++" ,
         "ruby" ,
],
type: [
{
         A: 1
         B: 5
},
{
         A: 2
         B: 6
},
],
encoding : "UTF-8"
indent_length : 3
indent_use_sapce : true

从输出结果来看,jsoncpp也可以灵活的生成和解析jsoncpp字符串,比QJson似乎更加容易上手一些呢。

那么,我们来简单对比下jsoncpp和QJson。

(1)格式上,jsoncpp相对于QJson生成的Json字符串来说,就是多了很多空格和换行符号,优点是 打印输出的json格式十分直观,缺点就是字符串长度变大,占用更多的存储空间,如果在网络传输中直接使用,会浪费较多的流量。所以如果使用Jsoncpp,我们实际项目中会对字符串进行优化,除空格和换行,甚至会使用字符串压缩技术,这部分我们在后面的文章中讲。

(2)QJson依赖于Qt组件,在Qt项目中使用还是很好的,但这也是他存在的局限性。在非Qt项目中,当然建议使用jsoncpp

 

附: 如何在嵌入式设备中使用 jsponcpp?

1、库文件编译如下,使用方法参照如上测试案例。

1、安装 scons
$ sudo apt-get install scons
$ scons platform=linux-gcc

2、编译jsconcpp库文件

mkdir arm_jsoncpp 
cp -r include/json arm_jsoncpp/ 
cp src/lib_json/* arm_jsoncpp/
cd arm_jsoncpp/

#create static dll
#arm-arago-linux-gnueabi-g++ -c *.cpp  -fPIC
#ar cr libjsoncpp.a *.o

#create dynamicall dll
arm-arago-linux-gnueabi-g++ -shared -fPIC *.cpp -o libjsoncpp.so


注意:在编译过程中如果出现以下的错误:
json_reader.cpp:1:25: fatal error: json/reader.h: No such file or directory
compilation terminated.
json_value.cpp:2:24: fatal error: json/value.h: No such file or directory
compilation terminated.
json_writer.cpp:1:25: fatal error: json/writer.h: No such file or directory
compilation terminated.

【解决方法:】头文件的路径不对。将<json/reader.h> 修改成"json/reader.h";其他几个文件也对应处理。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章