【C++】jsoncpp库问题一二

Json是数据交换经常使用的一种数据格式。C++标准库并无包含任何Json标准的实现,因此咱们要借助于一些第三方库,jsoncpp就是一个经常使用的库。因为工做中常常用jsoncpp,发现这个库问题很多,该篇文章本意是想深度吐槽一下这个函数库,但在寻找证据的过程当中发现部分问题是由版本形成的,因此对问题进行一些说明,但愿能帮助遇到一样问题的朋友。ios

异常致使程序终止

这也是我在工做中遇到的问题:在程序处理非法json串时,直接致使服务程序终止,即便使用try块包围这段代码,仍没法成功捕获异常。深刻阅读它的实现代码才发现,jsoncpp的异常处理是比较原始的,遇到异常直接assert,因此程序直接就终止了。对于简单的小程序来讲,这无可厚非,但对于后端服务来讲,这个问题很是严重,由于形成了服务不可用。json

通过再度挖掘,发现开发环境用的jsoncpp版本是0.5.0,因此异常处理机制原始;实际上在jsoncpp 0.8.3开始就对异常处理进行了改变,经过定义JSON_USE_EXCEPTION宏改变了类型无效的行为:小程序

If defined, indicates that Json use exception to report invalid type manipulation instead of C assert macro.

在最新版的1.8.4里,JSON_USE_EXCEPTION=1已是默认行为了,除了注释错误仍然调用assert外,基本上其余全部的错误都会抛出异常,再也不assert了:后端

If non-zero, the library uses exceptions to report bad input instead of C assertion macros. The default is to use exceptions.

因此,最简单的方案就是将库升级为最新版。若是由于一些缘由没法升级函数库,那最稳妥的方式就是在使用数据以前进行严格的数据检查,除此以外没有其余更好的方式。数组

对于哪些错误可能致使异常,在jsoncpp.cpp文件里直接搜关键字JSON_ASSERTJSON_FAIL_MESSAGEassert,找到对应异常所在的代码,可让你知道哪些具体状况会致使异常,以及哪些是可捕捉的,哪些会引发程序终止的。app

蹩脚的使用方式

说“蹩脚”,主要仍是由于它提供的API太老套,明显没跟上现代C++的步伐,同时跟C++的各种容器交互困难,大部分状况须要人工写代码。好比:ide

  • 缺少直观的初始化操做

现代C++加强了直观的初始化,好比map的初始化函数

std::map<int,int> map {{1,1},{2,2}};

但jsoncpp并无提供这类json常量的初始化,咱们只能经过:ui

Json::Value root;
    Json::FastWriter writer;

    root["name"] = "ideami";

    std::string json = writer.write(root);

    std::cout << json << std::endl;

人工构造,或者使用:idea

Json::Reader reader;
    Json::Value root;
    std::string jsonStr = "{\"name\":\"ideami\"}";
    if (!reader.parse(jsonStr, root)) {
        return -1;
    }

缺少直观性。

  • 不提供STL容器到Json结构的转换

std::vector<int>类型的数组,若生成json数组,咱们只能:

#include <iostream>
#include "json/json.h"
#include <string>

int main() {
    std::vector<int> v {1,2,3,4};

    Json::Value array;
    Json::FastWriter writer;

    for (auto e : v)
    {
        array.append(e);
    }

    std::cout << writer.write(array) << std::endl;
}

若是能提供直接转换的功能就方便了...

总体上,jsoncpp提供的API比较难用,上面用的API都是老版的API,其提供的新版APIJson::CharReaderBuilderJson::StreamWriterBuilder等易用性也不好。

在易用性上,JSON for Modern C++是一个更好的选择。

请继续关注个人公众号文章
图片描述

相关文章
相关标签/搜索