C++の応用 - JSON

提供: MochiuWiki : SUSE, EC, PCB

📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

概要

JSON (JavaScript Object Notation) は、軽量なデータ交換フォーマットである。
人間にとって読み書きが容易で、コンピュータにとっても解析や生成が容易なテキストベースのデータ形式である。

JSONは、元々JavaScriptのオブジェクト表記法から派生したが、現在では言語に依存しないデータ形式として広く使用されている。
多くのプログラミング言語がJSONの解析と生成をサポートしており、Web APIやアプリケーション間のデータ交換、設定ファイル等、様々な用途で利用されている。

JSONの特徴を以下に示す。

  • XMLと比較して軽量で記述が簡潔である。
  • Web APIのレスポンス形式として標準的に使用されている。
  • 設定ファイルやデータストレージとしても広く利用されている。


JSONのデータ型
データ型 説明
オブジェクト キーと値のペアの集合 {"name": "John", "age": 30}
配列 値の順序付きリスト [1, 2, 3, "test"]
文字列 ダブルクォーテーションで囲まれたテキスト "Hello"
数値 整数または浮動小数点数 123, 45.67
ブール値 真偽値 trueまたはfalse
null null値 null



JSON for Modern C++

JSON for Modern C++の概要

世の中には無数のJSONライブラリがあり、それぞれに存在理由がある。
JSON for Modern C++では、次のような設計目標がある。

  • 直感的な構文
    Python等のプログラム言語では、JSONはファーストクラスのデータ型のように見える。
    C++の演算子の全て使用して、コード内で同じ感覚を実現している。

  • 統合の簡素化
    ソースコード全体は、単一のヘッダファイルであるjson.hppファイルで構成されているのみである。
    ライブラリ、サブプロジェクト、依存関係、複雑なビルドシステムは不要である。
    JSON for Modern C++は、C++ 11で記述されており、コンパイラフラグやプロジェクト設定を調整する必要は無い。

  • 高い品質
    JSON for Modern C++は十分にテストされており、全ての例外的な動作を含むソースコードを100%カバーしている。
    また、ValgrindとClang Sanitizersでメモリリークが無いことを確認している。
    さらに、Google OSS-Fuzzは、全てのパーサーに対してファズテストを24時間年中無休で実行し、これまでに数十億のテストを効果的に実行している。
    高品質を維持するために、プロジェクトはコアインフラストラクチャイニシアチブ (CII)のベストプラクティスに従っている。

  • メモリ効率
    各JSON オブジェクトには、1つのポインタ (共用体の最大サイズ)と1つの列挙要素 (1バイト)のオーバーヘッドがある。
    デフォルトの汎化では、次のC++データ型が使用される。
    文字列の場合はstd::string
    数値の場合はint64_t、uint64_t、double
    オブジェクトの場合はstd::map
    配列の場合はstd::vector
    ブール値の場合はbool
    また、必要に応じて汎用クラスのBasic_jsonをテンプレート化することができる。

  • 開発効率
    より高速なJSONライブラリは存在するが、単一ヘッダファイルでJSONサポートを追加することにより、開発を高速化することができる。
    std::vectorクラスやstd::mapクラスの使用方法を知っていれば、すぐに使用することができる。


JSON for Modern C++は、MITライセンスである。

JSON for Modern C++のインストール

Linux

JSON for Modern C++のGithubにアクセスして、ソースコードをダウンロードする。
ダウンロードするファイルは、Source code (tar.gz)と記載されているリンクである。

ダウンロードしたファイルを解凍する。

tar xf json-<バージョン>.tar.xz
cd json-<バージョン>


JSON for Modern C++をビルドおよびインストールする。

mkdir build && cd build

cmake -DCMAKE_INSTALL_PREFIX=<JSON for Modern C++のインストールディレクトリ> ..
make -j $(nproc)
make install


Windows

JSON for Modern C++のGithubにアクセスして、ソースコードをダウンロードする。
ダウンロードするファイルは、include.zip または json.hpp と記載されているリンクである。

ダウンロードしたファイルを解凍する。
各プロジェクトファイルに配置して、json.hppをインクルードして使用する。

JSONファイルの読み込み

 #include <iostream>
 #include <fstream>
 #include "nlohmann/json.hpp"
 
 using namaspace std;
 
 // JSONファイルの読み込み
 string filename = "JSON-Sample.json";
 ifstream ifs(filename.c_str());
 
 if (ifs.good()) {
    json m_json;
    ifs >> m_json
 
    // 読み込んだデータを各変数へ代入
    string firstname = m_json["FirstName"];
    string lastname  = m_json["LastName"];
    int    age       = m_json["Age"];
    double height    = m_json["Height"];
 
    // 各データの表示
    cout << "firstname:" << firstname << endl;
    cout << "lastname:"  << lastname << endl;
    cout << "age:"       << age << endl;
    cout << "height:"    << height << endl;
 }
 else {
    // JSONファイルの読み込みに失敗した場合
    cout << "ファイルの読み込みに失敗しました" << endl;
 }


JSONファイルの書き込み

 #include <iostream>
 #include <fstream>
 #include "nlohmann/json.hpp"

 using namaspace std;
 
 // 書き込むJSONファイルの内容
 json m_json = {
    {"FirstName", "Jung kook"},
    {"LastName",  "Park"},
    {"Country",   "Korea"},
    {"Age",       25},
    {"Height"     180.5f}
 };
 
 // JSONファイルのパス
 string filename  = "JSON-Sample.json";
 
 // JSONファイルへ書き込み
 ofstream writing_file;
 writing_file.open(filename, ios::out);  // JSONファイルの作成またはオープン
 writing_file << m_json.dump() << endl;  // JSON型のオブジェクトを書き込むには、シリアライズを行う必要がある
 writing_file.close();                   // JSONファイルを閉じる


JSONファイルの編集

以下の例では、"Age"キーの値を30に変更、"Height"キーと値を削除している。

 # 編集前のJSONデータ (JSON-Sample.jsonファイル)
 
 {
    "FirstName": "Jung kook",
    "LastName":  "Park",
    "Country":   "Korea",
    "Age":       25,
    "Height":    180.5
 }


 #include <iostream>
 #include <fstream>
 #include "nlohmann/json.hpp"
 
 using namaspace std;
 
 using json = nlohmann::json;
 
 // JSONファイルの読み込み
 string filename = "JSON-Sample.json";
 ifstream ifs(filename.c_str());
 
 if (ifs.good()) {
    json m_json;
    ifs >> m_json;
 
    // ファイルを閉じる
    ifs.close();
 
    // Ageを30に変更
    m_json["Age"] = 30;
 
    // Heightを削除
    m_json.erase("Height");
 
    // 変更したJSONをファイルに書き込み
    ofstream writing_file;
    writing_file.open(filename, ios::out);
    writing_file << m_json.dump() << endl;
    writing_file.close();
 }
 else {
    // JSONファイルの読み込みに失敗した場合
    cout << "ファイルの読み込みに失敗しました" << endl;
 }