最新消息:

使用jsoncpp解析JSON数据

技术文章 NickYang 35377浏览 12评论

上节《JSON数据格式》中我们讲到了JSON的数据格式和一些应用的地方,接着上面的说下去,jsoncpp和boost.property_tree都可以解析JSON文件,我们先将jsoncpp如何解析。

1.jsoncpp是什么?

jsoncpp是一个使用C++语言来解析json文件的开源库,其项目地址为:http://sourceforge.net/projects/jsoncpp/,属于免费项目,任何人都可以下载使用

2. 编译jsoncpp

jsoncpp文件中提供了vs71的工程文件以及makerelease.py文件,用来编译,里面分为jsontest、lib_json、test_lib_json三个工程,按照自己需要的编译。

注意:如果使用VS默认的编译选项MTd或者MT,在使用json_libmtd.lib的时候可能会出现LNK2038错误(我使用的VS2012 vc110环境)所以请修改MTD为MDd,MT为MD

3.使用jsoncpp读JSON文件

如何将lib库添加进VS工程中在此就不赘述了。先看第一个读文件的例

// JSON文件
{"address":[
    {"name":"eliteYang", "email":"elite_yang@163.com"},
    {"name":"AAA", "email":"aaa@163.com"},
    {"name":"BBB", "email":"bbb@163.com"}
]}

/**
 * file     :   jsoncpp_test.cpp
 * author   :   eliteYang
 * email    :   elite_yang@163.com
 * blog     :   http://www.cppfasn.org
 * desc     :   json cpp test
 */
 
#include <fstream>
#include <string>
#include "jsoncpp/json.h"
 
int _tmain(int argc, _TCHAR* argv[])
{
    std::ifstream ifs;
    ifs.open("test.json");
 
    Json::Reader reader;
    Json::Value root;
    if (!reader.parse(ifs, root, false))
    { return -1; }
 
    Json::Value add_value = root["address"];
    for (int i = 0; i < add_value.size(); ++i)
    {
        Json::Value temp_value = add_value[i];
        std::string strName = temp_value["name"].asString();
        std::string strMail = temp_value["email"].asString();
        std::cout << "name: " << strName << " email: " << strMail << std::endl;
 
        // use value array[index]
        //Json::Value temp_value = add_value[i];
        //std::string strName = add_value[i]["name"].asString();
        //std::string strMail = add_value[i]["email"].asString();
        //std::cout << "name: " << strName << " email: " << strMail << std::endl;
    }
 
    system("Pause");
 
    return 0;
}

结果:

name: eliteYang email: elite_yang@163.com
name: AAA email: aaa@163.com
name: BBB email: bbb@163.com
请按任意键继续. . .

跟我们文件中的数据完全一致。

4.使用JSON写入一块数据

我们继续使用上述文件,在中间加上一块数据。我们插入一个新的{"name": "append", "email": "append@163.com"}

/**
 * file     :   jsoncpp_test.cpp
 * author   :   eliteYang
 * email    :   elite_yang@163.com
 * blog     :   http://www.cppfasn.org
 * desc     :   json cpp test
 */
 
#include <fstream>
#include <string>
#include "jsoncpp/json.h"
 
int _tmain(int argc, _TCHAR* argv[])
{
    std::ifstream ifs;
    ifs.open("test.json");
 
    Json::Reader reader;
    Json::Value root;
    if (!reader.parse(ifs, root, false))
    { return -1; }
 
    Json::Value& add_value = root["address"];
    Json::Value append_value;
    append_value["name"] = "append";
    append_value["email"] = "append@163.com";
    add_value.append(append_value);
 
    for (int i = 0; i < add_value.size(); ++i)
    {
        Json::Value temp_value = add_value[i];
        std::string strName = temp_value["name"].asString();
        std::string strMail = temp_value["email"].asString();
        std::cout << "name: " << strName << " email: " << strMail << std::endl;
    }
 
    Json::FastWriter writer;
    std::string json_append_file = writer.write(root);
 
    std::ofstream ofs;
    ofs.open("test_append.json");
    ofs << json_append_file;
 
    system("Pause");
 
    return 0;
}

结果:

name: eliteYang email: elite_yang@163.com
name: AAA email: aaa@163.com
name: BBB email: bbb@163.com
name: append email: append@163.com
请按任意键继续. . .
// test_append.json
{"address":[{"email":"elite_yang@163.com","name":"eliteYang"},{"email":"aaa@163.com","name":"AAA"},{"email":"bbb@163.com","name":"BBB"},{"email":"append@163.com","name":"append"}]}

当然了,jsoncpp对数组的解析也支持STL中迭代器的风格,不过我个人觉得还是数组好理解一些。迭代器的解析风格就不写了,大家可以自己摸索下,主要是使用Json::Value::Members。

JSON官方还是非常推荐用jsoncpp来解析JSON文件的,大家也看到了,确实比较方便。

btw.因为这两天笔记本散热不好,所以接了套螺丝刀将笔记本大卸八块,扫了扫灰,然后又装上了,结果神奇的就好了,果然是贱啊,欠拆。所以json系列的文章就晚了几天,非常抱歉,好了,不早了,该睡觉了,各位晚安。

转载请注明:C++爱好者博客 » 使用jsoncpp解析JSON数据

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

网友最新评论 (12)

  1. 因为json是弱语法,可能在解析时碰到需要的字段不存在的情况。 针对jsoncpp,我还做了一组专门的宏,当字段不存在时会抛出异常,这样碰到大量数据解析时可以省不少代码:#include #include//对于三个点(...)的可变参数,用此宏来快速打印。 #define VAR_PARAM_PRINT(TARGET_STRING, VAR_STRING) \ { \ va_list vp; \ va_start(vp, VAR_STRING); \ vsnprintf(TARGET_STRING, sizeof(TARGET_STRING), VAR_STRING, vp); \ va_end(vp); \ }class CJsonException { public: CJsonException(const char *pszErrMsg, ...) { VAR_PARAM_PRINT(m_szErrMsg, pszErrMsg); }const char *what() { return m_szErrMsg; }private: char m_szErrMsg[512]; };#define GetJsonArray(Node, Key) \ ({ \ if(false==Node.isMember(Key)) \ { \ throw CJsonException("Key [%s] does not exist", #Key); \ } \ \ if(Node[Key].isArray()) \ { \ } \ else if(Node[Key].isObject() && Node[Key].size()==0) /*compatible with UnrealEngine's JSON lib*/\ { \ } \ else if(Node[Key].isNull()) \ { \ } \ else \ { \ throw CJsonException("Key [%s] is not an array", #Key); \ } \ \ Node[Key]; \ })#define GetJsonObject(Node, Key) \ ({ \ if(!Node.isObject()) \ { \ throw CJsonException(#Node " is not an object"); \ } \ \ if(false==Node.isMember(Key)) \ { \ throw CJsonException("Key [%s] does not exist", #Key); \ } \ \ Node[Key]; \ })#define GetJsonData(Node, Key, Type) \ ({ \ if(!Node.isObject()) \ { \ throw CJsonException(#Node " is not an object"); \ } \ \ if(false==Node.isMember(Key)) \ { \ throw CJsonException("Key [%s] does not exist", #Key); \ } \ \ if(!Node[Key].is##Type()) \ { \ throw CJsonException("Key [%s] is not %s", #Key, #Type); \ } \ \ Node[Key].as##Type(); \ })
    小圆脸宝宝4年前 (2015-12-03)回复
  2. { "type": "ZH_CN2EN", "errorCode": 0, "elapsedTime": 1, "translateResult": [ [ { "src": "你好", "tgt": "How are you" } ] ] }src 和 tgt怎么解析出来,我的邮箱forcj@qq.com
    hinihao5年前 (2014-08-13)回复
    • 例子就在上面,你可以自己看下,你这种就是两个结构而已,继续往里读取就可以了
      eliteYang5年前 (2014-08-14)回复
  3. http://json.org/ 有很多json的编码解析器,我都是用的时候随便找个的。。。
    Yu Jing6年前 (2013-09-27)回复
    • 恩,这里面介绍了挺多库的,jsonpp,boost.property_tree等都可以
      eliteYang6年前 (2013-09-27)回复
  4. 很不错 谢谢分享。。
    heng6年前 (2013-08-06)回复
  5. 能透露一下广告费有多少么?一天或一个月。
    weiwangchao6年前 (2013-05-29)回复
    • 百来块钱吧,主要是没精力去写博客,只是偶尔写。
      eliteYang6年前 (2013-05-29)回复
      • 一天有一百的话不错啊,是条财路。
        dfasf6年前 (2013-05-29)回复
        • 是一个月,一天有这么多,那岂不是很爽?
          eliteYang6年前 (2013-05-30)回复
  6. 这网站是你自己的域名和服务器吗?广告收入自己拿?
    weiwangchao6年前 (2013-05-27)回复