C++使用Jsoncpp(VS2017 + jsoncpp-00.11.z + X64编译;)

说明

VS2017 + jsoncpp-00.11.z(目前最新版) + X64编译;
详细使用步骤,包括:下载编译Jsoncpp、VS2017功能设置、Jsoncpp使用举例;

Jsoncpp下载和编译

  1. 下载jsoncpp
    https://github.com/open-source-parsers/jsoncpp/tree/master

  2. 编译:
    cd D:\work\program\open_source\jsoncpp-00.11.z\jsoncpp-00.11.z
    //建一个编译工程目录,目录名随意
    mkdir build_2
    cd build_2
    //使用cmake编译,
    //我使用的VS2017自带的cmake.exe
    //“..” 表示CMakeLists.txt在外面的目录
    "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" ..
    // 如果编译x64版本增加参数: -G "Visual Studio 15 2017 Win64"
    "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" .. -G "Visual Studio 15 2017 Win64"

  3. 打开build_2/jsoncpp.sln 进行编译即可;
    一般而言,我们使用动态链接,(静态链接类似,不做介绍),那么需要如下几个目录:

  • 头文件目录


    image.png
  • 编译生成的bin目录,里面存放了动态库


    image.png
  • 编译生成的lib目录,里面存放了链接库


    image.png

VS2017使用Jsoncpp的工程设置

  1. 把jsoncpp的头文件、lib、dll拷过来:


    image.png

    PS:我是在工程中新建了jsoncpp-00.11.z\x64,然后拷贝过来;

  2. 设置lib库目录:


    image.png
  3. 设置lib库名称:


    image.png
  4. 设置头文件包含路径:


    image.png
  5. 设置dll目录,我们把工作目录改为输出目录,并把dll到输出目录,避免手动拷贝dll:

  • 链接结束时,拷贝dll到输出目录:


    image.png
  • 并把工作目录改为输出目录:


    image.png

Jsoncpp的使用

如下代码,包含main()函数,可以直接拷贝运行;

Json写文件

#include 
#include 
#include 

#include "json/json.h"
using namespace std;

int saveToFile(const string& file_name, const Json::Value& value)
{
    ofstream ofs; //标准输出流
    ofs.open(file_name); //创建文件
    if (!ofs.is_open())
    {
        cout << "error, open file failed. \n";
        return -1;
    }
    ofs << value.toStyledString(); //输出
    ofs.close();
    return 0;
}

int main(int argc, char** argv)
{
    Json::Value value; //定义根节点
    {
        Json::Value jsonItem; 
        jsonItem["item1"] = "one"; 
        jsonItem["item2"] = 2;
        value.append(jsonItem);

        jsonItem.clear(); 
        jsonItem["item1.0"] = 1.0;
        jsonItem["item2.0"] = 2.0;
        value.append(jsonItem);

        value.append("item3");
    }
    cout << "json data: \n" << value.toStyledString() << endl;

    if (saveToFile("didi_test.json", value) != 0)
    {
        return -1;
    }
    cout << "save to file OK. \n";

    return 0;
}

didi_test.json:


image.png

Jsoncpp支持注释

虽然json被强烈不建议添加注释,但是jsoncpp仍然支持注释,格式类似如下:didi_test_comments.json

// root info
[
    {
        "item1" : "one", /* item1 info */
        "item2" : 2
    },
    {
        "item1.0" : 1.0,
        "item2.0" : 2.0
    },
    "item3"
]

如下代码,读取该文件;

#include 
#include 
#include 

#include "json/json.h"
using namespace std;

int readFromFile(const Json::CharReaderBuilder& builder, const string& file_name, Json::Value& value)
{
    ifstream ifs; //标准输入流
    ifs.open(file_name);
    if (!ifs.is_open())
    {
        cout << "error, open file failed. \n";
        return -1;
    }

    JSONCPP_STRING errs;
    if (!parseFromStream(builder, ifs, &value, &errs)) //从ifs中读取数据到jsonRoot
    {
        cout << "error, parseFromStream failed. \n";
        return -1;
    }

    return 0;
}

int main(int argc, char** argv)
{
    Json::Value value;

    Json::CharReaderBuilder builder;
    builder["collectComments"] = true;
    builder["allowComments"] = true;

    if (readFromFile(builder, "didi_test_comments.json", value) != 0)
    {
        return -1;
    }

    cout << "read from file with Comments:\n" << value.toStyledString() << endl;
    return 0;
}

输出:


image.png

PS:读到的数据也是带注释的;后续写入文件也可以包含注释;

Jsoncpp的序列化和反序列化

Json序列化,即把Json数据转换成字符串,以便于发给其他进程或网络间进行数据通讯;
Jsoncpp序列化时,类似于大端,即高位在前,低位在后,十进制方式(而不是十六进制)从高位到低位取出每位的值,依次存放到字符串中:

比如:


image.png

参见Jsoncpp实现代码valueToString()方法:

enum {
    /// Constant that specify the size of the buffer that must be passed to
    /// uintToString.
    uintToStringBufferSize = 3 * sizeof(uint64_t) + 1
};

// Defines a char buffer for use with uintToString().
typedef char UIntToStringBuffer[uintToStringBufferSize];

static inline void uintToString(uint64_t value, char*& current) {
    *--current = 0;
    do {
        *--current = static_cast(value % 10U + static_cast('0'));
        value /= 10;
    } while (value != 0);
}

string valueToString(uint64_t value) {
    UIntToStringBuffer buffer;
    char* current = buffer + sizeof(buffer);
    uintToString(value, current);
    assert(current >= buffer);
    return current;
}

你可能感兴趣的:(C++使用Jsoncpp(VS2017 + jsoncpp-00.11.z + X64编译;))