JsonCpp使用注意


JsonCpp 的使用
JSON全稱為JavaScript ObjectNotation,它是一種輕量級的數據交換格式,易於閱讀、編寫、解析。jsoncpp是c++解析JSON串常用的解析庫之一。

jsoncpp中主要的類:

Json::Value:可以表示所有支持的類型,如:int , double ,string , object, array等。其包含節點的類型判斷(isNull,isBool,isInt,isArray,isMember,isValidIndex等),類型獲取(type),類型轉換(asInt,asString等),節點獲取(get,[]),節點比較(重載<,<=,>,>=,==,!=),節點操作(compare,swap,removeMember,removeindex,append等)等函數。
Json::Reader:將文件流或字符串創解析到Json::Value中,主要使用parse函數。Json::Reader的構造函數還允許用戶使用特性Features來自定義Json的嚴格等級。
Json::Writer:與JsonReader相反,將Json::Value轉換成字符串流等,Writer類是一個純虛類,並不能直接使用。在此我們使用 Json::Writer 的子類:Json::FastWriter(將數據寫入一行,沒有格式),Json::StyledWriter(按json格式化輸出,易於閱讀)

 

JsonCpp使用注意點:

1.對不存在的鍵獲取值會返回此類型的默認值。
2.通過key獲取value時,要先判斷value的類型,使用錯誤的類型獲取value會導致程序中斷。
3.獲取json數組中某一項key的value應該使用value[arraykey][index][subkey]獲取或循環遍歷數組獲取。
4.append函數功能是將Json::Value添加到數組末尾。

5.由於Jsoncpp解析非法json時,會自動容錯成字符類型。對字符類型取下標時,會觸發assert終止進程。
解決方法:啟用嚴格模式,讓非法的json解析時直接返回false,不自動容錯。這樣,在調用parse的時候就會返回false。

Json::Reader *pJsonParser = new Json::Reader(Json::Features::strictMode());
 

判斷json字符串中是否存在某鍵值的幾種方法:

1.value.isMember("key");    //存在返回true,否則為false
2.value["sex"].isNull();    //為NULL返回1,否則為0
 

JsonCpp讀寫示例代碼:

復制代碼
#include <iostream>
#include <sstream>
#include <fstream>
#include <json/json.h>

void readJsonFromFile()
{
    std::ifstream ifs;
    ifs.open("a.json");
    std::stringstream buffer;
    buffer << ifs.rdbuf();
    ifs.close();

    auto str = buffer.str();

    Json::Reader reader;
    Json::Value value;
    if (reader.parse(str, value)) {
        //節點判斷
        std::cout << "value's empty:" << value.empty() << std::endl;
        std::cout << "name is string:" << value["name"].isString() << std::endl;
        std::cout << "age is string:" << value["age"].isString() << std::endl;

        //類型獲取
        std::cout << "name's type:" << value["name"].type() << std::endl;
        std::cout << "like's type:" << value["like"].type() << std::endl;

        //類型轉換
        //根據Key獲取值時最好判斷類型,否則解析會中斷
        std::cout << "name:" << value["name"].asString() << std::endl;
        std::cout << "age:" << value["age"].asInt() << std::endl;

        //節點獲取
        std::cout << value["job"] << std::endl;                        //[]方式獲取
        std::cout << value.get("name", "dxx") << std::endl;            //get方式獲取
        std::cout << value.isMember("job") << std::endl;
        std::cout << "value's obj:" << value.isObject() << std::endl;
        std::cout << "like's obj:" << value["like"].isObject() << std::endl;

        std::cout << "like.size:" << value["like"].size() << std::endl;
        std::cout << "like[0][food]:" << value["like"][0]["food"].asString() << std::endl;

        //節點操作
        std::cout << "name compare age:" << value["name"].compare("age") << std::endl;
        value["name"] = "swduan";            //修改
        value["address"] = "hz";             //增加
        value["phone"] = "10086";        
        value.removeMember("age");           //刪除
        value["like"][0]["sport"] = "game";  //往value["like"]中添加一項元素

        Json::Value item;
        item["hate"] = "game";
        value["like"].append(item);            //value["like"]中再添加一維數組
        std::cout << "value[\"like\"]'s size:" << value["like"].size() << std::endl;
        
        std::cout << "--------------------" << std::endl;
        std::cout << value.toStyledString() << std::endl;

        std::cout << "--------------------" << std::endl;
        auto all_member = value.getMemberNames();
        for (auto member : all_member) {
            std::cout << member << std::endl;
        }

        std::cout << "--------------------" << std::endl;
        value.clear();        //清空元素
        std::cout << value.toStyledString() << std::endl;
    }
}

void jsonWriteToFile()
{
    Json::FastWriter write;
    Json::Value root;

    Json::Value item;
    Json::Value arrayObj;
    item["book"] = "c++";
    item["food"] = "apple";
    item["music"] = "ddx";
    arrayObj.append(item);

    root["name"] = "dsw";
    root["age"]  = 18;
    root["like"] = arrayObj;    //注意:這里不能用append,append功能是將Json::Value添加到數組末尾

    auto str = root.toStyledString();
    std::cout << str << std::endl;

    std::ofstream ofss;
    ofss.open("a.json");
    ofss << str;
    ofss.close();
}

int main()
{
    jsonWriteToFile();
    readJsonFromFile();

    getchar();
    return 0;
}
復制代碼
輸出:


復制代碼
value's empty:0
name is string:1
age is string:0
name's type:4
like's type:6
name:dsw
age:18
null
"dsw"
1
value's obj:1
like's obj:0
like.size:1
like[0][food]:apple
name compare age:1
value["like"]'s size:2
--------------------
{
   "address" : "hz",
   "job" : null,
   "like" : [
      {
         "book" : "c++",
         "food" : "apple",
         "music" : "ddx",
         "sport" : "game"
      },
      {
         "hate" : "game"
      }
   ],
   "name" : "swduan",
   "phone" : "10086"
}

--------------------
address
job
like
name
phone
--------------------
{}

示例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;
}


免責聲明!

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



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