使用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";其他幾個文件也對應處理。

 

 

 

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