json簡介及JsonCpp用法


[時間:2017-04] [狀態:Open]
[關鍵詞:數據交換格式,json,jsoncpp,c++,json解析,OpenSource]

json簡介

本文僅僅是添加我個人對json格式的理解,更詳細的格式建議參考官網的JSON介紹及標准文檔。

json中僅支持兩種結構:

  • name->value鍵值對(pair)的集合,一般稱為對象(object)。
  • 值的有序表,一般稱為數組(array)。

1. pair

先從鍵值對(pair)開始,一個pair的通常結構是:
string:value
鍵值之間的對應關系使用:表示,左邊的為name,右邊的為value。
一般key使用字符串,當然也可以使用數字,但是不推薦。
value的取值就比較隨便,可以是任何任何json支持的類型(比如object,array,string,number,true/false,null等)。

2. object

object可以認為是多個pair的集合,官網上給出的示意圖如下:
object結構示意圖
其語法是以{作為object開始,以}作為object結束,不同的pair之間使用,分割。
需要說明的是object中的數據存儲是無序的。

下面是一個比較典型的object構成

{
"name" : "tocy",
"age" : 1000
}

3. array

array是value的有序集合。先看官網上針對array結構的示意圖:
array結構示意圖
其語法是以[作為array起始,以]作為array結束,array元素之間使用,分割。
實際使用中建議在array中使用統一的類型,否則解析起來會麻煩點。
比如下面語法是合法的:

[{"name":"tocy"}, {"age":1000}, {"domain":"cn"}]

當然下面這種寫法也是可以的,[1, "ts", true, {"key":45}]

至於其他的string和number支持的格式,建議參考json官方介紹。

JsonCpp的使用

json的官網上有很多關於json解析的工具,可以從中選擇一個你喜歡的。
我主要在c++下使用json,我選擇了JsonCpp,官網是:https://github.com/open-source-parsers/jsoncpp。
下載完源碼之后為了使用方便,直接將源碼嵌入到工程中,進入源碼所在目錄,先生成一個完整的頭文件和cpp文件,命令如下:

python amalgamate.py

然后將dist文件夾拷貝到工程目錄就可以使用了。(包含json/json.h、json/json-forwards.h、json.cpp)
注意:本部分用例代碼可能為了簡化期間,並未做錯誤異常判斷,僅供參考。

示例1 從文件中讀取json文件並解析


首先我們提供一個json文件,這里命名為"checkjson.json",其中數據如下:

{
    "name" : "tocy",
    "age" : 1000
}

這里面保存的是最簡單的object,我們可以使用下面代碼將其讀入並解析:

void demo_simple()
{
    ifstream ifs;
    ifs.open("checkjson.json");
    assert(ifs.is_open());
 
    Json::Reader reader;
    Json::Value root;
    if (!reader.parse(ifs, root, false))
    {
        cerr << "parse failed \n";
        return;
    }
 
    string name = root["name"].asString(); // 實際字段保存在這里
    int age = root["age"].asInt(); // 這是整型,轉化是指定類型
}

這里是簡單的map訪問,然后直接讀取對應字段即可。

示例2 從內存中讀取json數據(object)


我們在內存中定義一段json數據,然后解析,這次我們在json中添加內嵌array的object。代碼如下:

void demo_parse_mem_object()
{
    const char json_data[] = 
        "{\"name\" : \"Tocy\", \"salary\" : 100, \"msg\" : \"work hard\", \
        \"files\" : [\"1.ts\", \"2.txt\"]}";  

    Json::Reader reader;
    Json::Value root;
    // reader將Json字符串解析到root,root將包含Json里所有子元素  
    if (!reader.parse(json_data, json_data + sizeof(json_data), root))
    {
        cerr << "json parse failed\n";
        return;
    }
    
    cout << "demo read from memory ---------\n";
    string name = root["name"].asString();
    int salary = root["salary"].asInt();
    string msg = root["msg"].asString();
    cout << "name: " << name << " salary: " << salary;
    cout << " msg: " << msg << endl;
    cout << "enter files: \n";
    Json::Value files = root["files"]; // read array here
    for (unsigned int i = 0; i < files.size(); ++i)
    {
        cout << files[i].asString() << " ";
    }
    cout << endl << endl;
}

示例3 從內存中解析json數據(array)


這次我們從提供一個以array封裝的json數據,解析邏輯如下:

void demo_parse_mem_array()
{
    const char json_data[] = 
        "[{\"name\" : \"Tocy\", \"salary\" : 100}, {\"name\" : \"Kit\", \"salary\" : 89}, \
        \"a json note\"]";  

    Json::Reader reader;
    Json::Value root;
    // reader將Json字符串解析到root,root將包含Json里所有子元素  
    if (!reader.parse(json_data, json_data + sizeof(json_data), root))
    {
        cerr << "json parse failed\n";
        return;
    }
    
    cout << "demo read from memory using array---------\n";
    unsigned int count = root.size() - 1;
    for (unsigned int i = 0; i < count; ++i)
    {
        string name = root[i]["name"].asString();
        int salary = root[i]["salary"].asInt();
        cout << "name: " << name << " salary: " << salary << endl;
    }
    cout << "last msg: " << root[count].asString() << endl;
    cout << endl << endl;
}

示例4 簡單json數據封裝

前面三個是關於json數據解析的例子,下面是關於json數據封裝的例子。
首先我們生成示例1的數據,代碼如下:

void demo_write_simple()
{
    Json::Value root;
    Json::FastWriter writer;
    Json::Value person;
 
    person["name"] = "tocy";
    person["age"] = 1000;
    root.append(person);
 
    string json_file = writer.write(root);

    cout << "demo write json ==============\n";
    cout << json_file << endl;
}

示例5 json封裝-內嵌array的object

首先我們生成示例2的數據,代碼如下:

void demo_write_object()
{
    Json::Value root;
    Json::FastWriter writer;
 
    root["name"] = "tocy";
    root["salary"] = 100;
    root["msg"] = "work hard";
    Json::Value files;
    files[0] = "1.ts";
    files[1] = "2.txt";
    root["files"] = files;
 
    string json_file = writer.write(root);
    cout << "demo write json object ==============\n";
    cout << json_file << endl;
}

示例6 json封裝-內嵌object的array

首先我們生成示例3的數據,代碼如下:

void demo_write_array()
{
    Json::Value root;
    Json::FastWriter writer;

    {
        Json::Value person; 
        person["name"] = "Tocy";
        person["salary"] = 100;
        root[0] = person;
    }
    
    {
        Json::Value person; 
        person["name"] = "Kit";
        person["salary"] = 89;
        root[1] = person;
    }
    
    root[2] = "a json note";   
 
    string json_file = writer.write(root);
    cout << "demo write json ==============\n";
    cout << json_file << endl;
}

小結

本文簡單整理了json相關格式。同時針對JsonCpp的用法做簡單總結,僅供參考。

本文相關源碼,可以從我的git下載,位於JsonCppTutorial目錄下。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM