プログラミングの際,パラメータをファイル入力にしておくことで,コードの変更なくパラメータ調整ができるというのは当たり前の話ですが,面倒だからと後回しにしてハードコーディングしてしまっている学生をたびたび見かけます.程度の差こそあれ,大体の理由は実装が面倒だから.
かく言う私も,Cross-Platform-Dense-SLAMの実装でもやっているようにstd::ifstream
を使って1行ずつ読んでいくようなことをやってしまっています.今回はこのあたりをきちんと実装している人からのお勧めに基づいて,JSON (JavaScript Object Notation)を使ってみることにしました.
JSON用ライブラリ
先述のちゃんとしている人から勧められたnlohmann/jsonを使います.必要な情報がすべて書かれているためかトップページが仰々しいですが,ヘッダオンリーのライブラリということもあり大変扱いやすいです.準備としては,公式ページのココからjson.hpp
をダウンロードして所望のフォルダに入れておくだけです.
ちなみにRapidJSONなるものもあるとか.
テスト用JSONファイルとC++コード
以下のようなファイル構成になっているとします.ということでinput_params.json
とMain.cpp
を書いていきます.
ROOT ├─data │ input_params.json └─sources │ Main.cpp └─nlohmann json.hpp
なんとなく自分の利用用途を想定して以下のようなJSONファイルinput_params.json
を作ってみました.window
以下に入れ子でname
,width
,height
が入っています.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