Mugichoko's blog

Mugichoko’s blog

プログラミングを中心としたメモ書き.

JSONを使ってみる

プログラミングの際,パラメータをファイル入力にしておくことで,コードの変更なくパラメータ調整ができるというのは当たり前の話ですが,面倒だからと後回しにしてハードコーディングしてしまっている学生をたびたび見かけます.程度の差こそあれ,大体の理由は実装が面倒だから.

かく言う私も,Cross-Platform-Dense-SLAMの実装でもやっているようにstd::ifstreamを使って1行ずつ読んでいくようなことをやってしまっています.今回はこのあたりをきちんと実装している人からのお勧めに基づいて,JSON (JavaScript Object Notation)を使ってみることにしました.

JSON用ライブラリ

先述のちゃんとしている人から勧められたnlohmann/jsonを使います.必要な情報がすべて書かれているためかトップページが仰々しいですが,ヘッダオンリーのライブラリということもあり大変扱いやすいです.準備としては,公式ページのココからjson.hppをダウンロードして所望のフォルダに入れておくだけです.

github.com

ちなみにRapidJSONなるものもあるとか.

テスト用JSONファイルとC++コード

以下のようなファイル構成になっているとします.ということでinput_params.jsonMain.cppを書いていきます.

ROOT
├─data
│      input_params.json
└─sources
    │  Main.cpp
    └─nlohmann
            json.hpp

なんとなく自分の利用用途を想定して以下のようなJSONファイルinput_params.jsonを作ってみました.window以下に入れ子namewidthheightが入っています.intrinsicsも同様に入れ子になっています.

{
  "project name": "JSON test",
  "window": {
    "name": "OpenGL window",
    "width": 640,
    "height": 480
  },
  "intrinsics": {
    "fx" : 525.0,
    "fy" : 525.0,
    "cx" : 319.5,
    "cx" : 239.5
  }
}

以下のコードでデータを読み込んでみます.16~19行目がJSONファイルに入っている情報をすべて出力する例で,21,22行目が1要素ずつ出力する例です.namespace nl = nlohmann;は単にネームスペースが長いので短くしただけです.

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

namespace nl = nlohmann;

const std::string pathToJSON("../data/input_params.json");

int main()
{
    std::ifstream ifs(pathToJSON.c_str());
    if (ifs.good())
    {
        nl::json j;
        ifs >> j;
        for (const auto &elem : j.items())
        {
            std::cout << elem.value() << std::endl;
        }

        std::cout << j["project name"] << std::endl;
        std::cout << j["intrinsics"]["cx"] << std::endl;
    }

    return 0;
}

実行すると,以下の様に出力されました.簡単でした.この程度なら面倒くさがらずにできると思います.これからはJSONを使っていくことにします.

> {"cx":239.5,"fx":525.0,"fy":525.0}
> "JSON test"
> {"height":480,"name":"OpenGL window","width":640}
> 
> "JSON test"
> 239.5