Cpp Library 之 JsonCpp

JSONCPP是C++中的生成与解析JSON 字符串的一种实现。JSON(JavaScript Object Notation, JS 对象简谱)是一种人比较容易理解,机器也比较容易解析的轻量级的数据交换格式。

JSON的例子:

{"firstName": "Brett", "lastName": "McLaughlin"}   
{
    "country": "中国",
    "province": [{
        "name": "黑龙江",
        "cities": {
            "city": ["哈尔滨", "大庆"]
        }
    }, {
        "name": "广东",
        "cities": {
            "city": ["广州", "深圳", "珠海"]
        }
    }, {
        "name": "台湾",
        "cities": {
            "city": ["台北", "高雄"]
        }
    }, {
        "name": "新疆",
        "cities": {
            "city": ["乌鲁木齐"]
        }
    }]
}

 

参考:
https://www.jianshu.com/p/987e95cc79f4
http://www.cppblog.com/wanghaiguang/archive/2013/12/26/205020.html
https://blog.csdn.net/fishman_yinwang/article/details/78029309
https://blog.csdn.net/u010442009/article/details/38401351
https://blog.csdn.net/shaosunrise/article/details/84680602

下载JsonCpp的地址:https://github.com/open-source-parsers/jsoncpp

注意:1.x.x的版本要编译器支持C++11,  0.x.x的可以不支持。由于VS2013编译1.x.x 版本报错,故使用了 0.5.0  下载:http://sourceforge.net/projects/jsoncpp/

    编译:下载并解压jsoncpp源代码后,你会得到文件夹jsoncpp-src-0.5.0,依次定位到jsoncpp-src-0.5.0/makefiles/vs71,里面就是VC++的项目文件了.你可以用VS打开jsoncpp.sln,里面有3个project:jsontest, lib_json和test_lib_json。
    选择Debug编译 生成 json_vc71_libmtd.lib,选择Release编译 生成 json_vc71_libmt.lib 。

    这里要注意的是:“运行lib_json项目前要设置一下c/c++-》代码生成-》运行库以便生成不一样的lib文件”
    如果lib要用于MTd环境下,则设置为MTd;如果lib要用于MDd环境下,则设置为MDd

问题解决:
1. Release下使用lib库出现错误 ...src\lib_json\json_reader.cpp : fatal error C1083: 无法打开编译器生成的文件: “../../build/vs71/release/lib_json\json_reader.asm”: No such file or directory
1>LINK : fatal error LNK1257: 代码生成失败。
办法:修改生成静态库文件的工程的属性:路径为:菜单-项目-属性-配置属性-c/c++ - 输出文件-汇编程序输出:无列表。lib_json项目中汇编程序输出原配置为:带源代码的程序集(/FAs),改为:无列表生成即可。        参见 https://blog.csdn.net/daiafei/article/details/49307073

2. 新版的JsonCpp的使用,用reader.parse函数时,可能出现“Use CharReader and CharReaderBuilder instead”的错误,可以用 #pragma warning(disable:4996) 解决

 这里是我编译好的:https://pan.baidu.com/s/1w3FosadxoRsQIrjUlPGM6A  提取码:du1c

#include <iostream>
#include <string>
#include "json/json.h"
#pragma comment(lib,"./build/debug/lib_json/json_vc71_libmtd.lib")
int main(void)
{
    std::string strValue = "{\"key1\":\"value1\",\"array\":[{\"key2\":\"value2\"},{\"key2\":\"value3\"},{\"key2\":\"value4\"}]}";
    Json::Reader reader;//json解析
    Json::Value value;//表示一个json格式的对象
    // 注意:当strJson中有单个 \ 字符(0x5c)时,解析失败。有 \n 可以。Big5编码的“許功蓋”里面含有0x5c可能解析不出来。
    if (reader.parse(strValue, value))//解析出json放到json中区
    {
        std::string out = value["key1"].asString();
        std::cout << out << std::endl;
        const Json::Value arrayObj = value["array"];//迭代器
        std::cout << "array:\n";
        for (int i = 0; i < arrayObj.size(); i++)
        {
            out = arrayObj[i]["key2"].asString();
            std::cout << '\t' << out;
            if (i != arrayObj.size() - 1)
                std::cout << std::endl;;
        }
    }

    getchar();
    return 0;
}
View Code

 解析Json

自己写的解析,解析上面的 “中国”的JSON

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

#if defined _DEBUG
    #pragma comment(lib,"./build/debug/lib_json/json_vc71_libmtd.lib")
    //#pragma comment(lib,"./build/debug/lib_json/json_vc71_libMDd.lib")
#else
    #pragma comment(lib,"./build/release/lib_json/json_vc71_libmt.lib")
    //#pragma comment(lib,"./build/release/lib_json/json_vc71_libMD.lib")
#endif

int main(void)
{
    //从一个json文件中读 reader.parse(ifile, root); 从json字符串读 reader.parse(sJson, root);
    std::ifstream ifile("testjson.txt",std::ios::binary);
    if (!ifile.is_open())
        return -1;
    std::stringstream buffer;
    buffer << ifile.rdbuf();
    std::string sJson(buffer.str());

    ifile.seekg(0, std::ios::beg);//std::ios::beg=SEEK_SET=0 //移动到文件开头

    Json::Reader reader;
    Json::Value root; //Json::Value是一种很重要的类型,可以代表任意类型。如int, string, object, array
    bool ret = reader.parse(ifile, root);//可以解析中文,但当有 \ (0x5c)时,可能会出错
    if (!ret)
        return -2;
    std::string sCountry = root["country"].asString();
    const Json::Value arr = root["province"];
    for (size_t i = 0; i < arr.size(); ++i)
    {
        std::string sName = arr[i]["name"].asString();
        const Json::Value obj = arr[i]["cities"];
        const Json::Value arrCity = obj["city"];
        for (size_t j = 0; j < arrCity.size(); ++j)
        {
            std::string sCity = arrCity[j].asString();
        }
    }
    return 0;
}
View Code

生成Json

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

#if defined _DEBUG
    #pragma comment(lib,"./build/debug/lib_json/json_vc71_libmtd.lib")
    //#pragma comment(lib,"./build/debug/lib_json/json_vc71_libMDd.lib")
#else
    #pragma comment(lib,"./build/release/lib_json/json_vc71_libmt.lib")
    //#pragma comment(lib,"./build/release/lib_json/json_vc71_libMD.lib")
#endif

int main(void)
{
    Json::Value root, arrProvince, ObjCities, arrCity;
    Json::FastWriter writer;

    root["country"] = "中国";

    arrCity[0u] = "哈尔滨";
    arrCity[1] = "大庆";
    ObjCities["city"] = arrCity;
    arrProvince[0u]["name"] = "黑龙江";
    arrProvince[0u]["cities"] = ObjCities;

    arrCity.clear(); ObjCities.clear();
    arrCity[0u] = "广州";
    arrCity[1] = "深圳";
    arrCity[2] = "珠海";
    ObjCities["city"] = arrCity;
    arrProvince[1]["name"] = "广东";
    arrProvince[1]["cities"] = ObjCities;

    arrCity.clear(); ObjCities.clear();
    arrCity[0u] = "乌鲁木齐";
    ObjCities["city"] = arrCity;
    arrProvince[2]["name"] = "新疆";
    arrProvince[2]["cities"] = ObjCities;

    root["province"] = arrProvince;

    std::string sJson = writer.write(root);
    
    return 0;
}
/* 注意:生成的json,key是按字母排好序的,可能跟添加的顺序不相同;但不影响解析,解析直接用key值查找,仍然可以用上面的解析程序去解析
    {"country":"中国","province":[{"cities":{"city":["哈尔滨","大庆"]},"name":"黑龙江"},{"cities":{"city":["广州","深圳","珠海"]},"name":"广东"},{"cities":{"city":["乌鲁木齐"]},"name":"新疆"}]}
*/
View Code

 

posted @ 2019-11-08 23:44  htj10  阅读(564)  评论(0编辑  收藏  举报
TOP