close

C++ 與 JSON - 使用 JSON for Modern C++

JSON for Modern C++ 和 utf-8 的測試

環境
windows 11 64bit
Visual Studio 2022

因為我通常都是讀檔,所以只測試讀檔的部分

https://github.com/nlohmann/json

下載下來之後,加入 include 目錄

001.jpg

 

 

1. 簡單測試

用記事本製作一個 simple.json,這預設會是一個 utf-8 的檔案

003.jpg

main.cpp

#include <iostream>
#include <fstream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;

int main() 
{
    json j;
    std::ifstream jfile("simple.json");
    jfile >> j;
    jfile.close();

    std::cout << "json j = " << j << std::endl;

    bool ok = j.at("ok");
    float height = j["height"];
    int width = j["width"];
    std::string name = j.at("name");

    std::cout << "ok = " << ok << std::endl;
    std::cout << "height = " << height << std::endl;
    std::cout << "width = " << width << std::endl;
    std::cout << "name = " << name << std::endl;

    system("pause");
    return 0;
}

執行結果

004.jpg

 

2. utf-8 字元測試

以前工作常遇到多國語言的部分,所以每次做檔案或字串處理,我都一定會用日文做 unicode 的測試。

用剛剛的 simple.json 改個日文字串直接存成 simple2.json。

005.jpg

直接把剛剛的程式碼改成讀取 simple2.json

#include <iostream>
#include <fstream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;

int main() 
{
    json j;
    std::ifstream jfile("simple2.json");	//直接改檔名
    jfile >> j;
    jfile.close();

    std::cout << "json j = " << j << std::endl;

    bool ok = j.at("ok");
    float height = j["height"];
    int width = j["width"];
    std::string name = j.at("name");

    std::cout << "ok = " << ok << std::endl;
    std::cout << "height = " << height << std::endl;
    std::cout << "width = " << width << std::endl;
    std::cout << "name = " << name << std::endl;

    system("pause");
    return 0;
}

執行結果雖然沒當機,但出現錯誤,而且還滿嚴重,不只 j 沒輸出完,後面的資料也拿不到。

006.jpg

開始修理,首先,把 j 改成 j.dump()

#include <iostream>
#include <fstream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;

int main() 
{
    json j;
    std::ifstream jfile("simple2.json");	//直接改檔名
    jfile >> j;
    jfile.close();

    //把 j 改成 j.dump()
    std::cout << "json j = " << j.dump() << std::endl;

    bool ok = j.at("ok");
    float height = j["height"];
    int width = j["width"];
    std::string name = j.at("name");

    std::cout << "ok = " << ok << std::endl;
    std::cout << "height = " << height << std::endl;
    std::cout << "width = " << width << std::endl;
    std::cout << "name = " << name << std::endl;

    system("pause");
    return 0;
}

執行結果在 utf-8 顯示以外的部分算是正常,後面的數值也都正確,另外也可以發現,這個 json 物件,似乎會自己做排序。

007.jpg

再來顯示 utf-8 的部分,因為我以前有一個 utf-8 轉 unicode 的函式,所以就直接用再 print 出來。

#include <iostream>
#include <fstream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;

int main() 
{
    json j;
    std::ifstream jfile("simple2.json");
    jfile >> j;
    jfile.close();

	//把 j 改成 j.dump()
    std::cout << "json j = " << j.dump() << std::endl;

    bool ok = j.at("ok");
    float height = j["height"];
    int width = j["width"];
    std::string name = j.at("name");

    std::cout << "ok = " << ok << std::endl;
    std::cout << "height = " << height << std::endl;
    std::cout << "width = " << width << std::endl;
    
    //對 name 的 utf-8 做處理
    std::wstring nameUni = hkstr::UTF8ToUnicode(name);    //把 utf-8 轉成 unicode
    hkstr::PrintfUnicode(L"name = %s\n", nameUni.c_str());  //把 unicode 印出來

    system("pause");
    return 0;
}

執行結果

008.jpg

 

3. 判斷資料是否存在
準備一個這樣的檔案

101.jpg

#include <iostream>
#include <fstream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;

int main() 
{
    json j;
    std::ifstream jfile("rank2.json");
    jfile >> j;
    jfile.close();

    std::cout << "json j = " << j.dump() << std::endl;

    std::cout << std::endl;

    std::string name;
    std::wstring nameUni;
    int score;

    json j4 = j["4"];
    std::cout << "json j4 = " << j4.dump() << std::endl;
    name = j4.at("name");
    nameUni = hkstr::UTF8ToUnicode(name);
    hkstr::PrintfUnicode(nameUni.c_str());
    std::cout << std::endl;
    score = j4.at("score");
    std::cout << "score = " << score << std::endl;

    std::cout << std::endl;

    json j5 = j["5"];
    std::cout << "json j5 = " << j5.dump() << std::endl;
    name = j5.at("name");
    nameUni = hkstr::UTF8ToUnicode(name);
    hkstr::PrintfUnicode(nameUni.c_str());
    std::cout << std::endl;
    score = j5.at("score");
    std::cout << "score = " << score << std::endl;

    std::cout << std::endl;

    json j6;
    //j6 = j.at("6");   //無法判斷資料是否存在
    j6 = j["6"];
    if (j6 == nullptr)
    {
        std::cout << "6 is not exist." << std::endl;
    }

    system("pause");
    return 0;
}

執行結果

102.jpg

 

參考資料

https://github.com/nlohmann/json
https://json.nlohmann.me/
https://nlohmann.github.io/json/doxygen/index.html
https://iter01.com/545198.html

arrow
arrow
    文章標籤
    C++ JSON JSON for Modern C++
    全站熱搜

    kamory 發表在 痞客邦 留言(0) 人氣()