今回はC++でjsonデータを取り扱ってみたいと思います。
簡単なcsvデータ(カンマ区切りのみ)であれば文字列をparseすればよいだけなので簡単なのですが、
jsonデータってどうやればよいのだろう??
と気になったので調べてみました!!
今回は調べて動かした内容の備忘録をまとめたいと思います。
- ■jsonデータを扱うためには?
- ■json型の文字列をjsonオブジェクトに変換
- ■jsonオブジェクトを文字列に変換
- ■jsonファイルからjsonデータを読み出し・取り扱い
- ■ビルド時のwarning対応
- ■最後に
- ■参考
■jsonデータを扱うためには?
調べてみたところ、nlohmannより公開されているライブラリを用いるのが手っ取り早いようでした。
ライセンスはMITでした。
github.com
こちらのgithubの
「single_include/nlohmann/」
配下の”json.hpp”を作成しているソースコードと同階層に格納すればライブラリが使用できます。
※Linuxの場合にはinclude配下に格納してもよいです。
■json型の文字列をjsonオブジェクトに変換
ではまずは文字列をjson型のオブジェクトに変換してみます。
コードはこちら。
#include <iostream> #include "json.hpp" void main(){ std::string jsonstr = R"({ "str":"こんにちは", "boolian":false, "person":[ { "name":"Taro", "age":20 }, { "name":"Tom", "age":30 } ] })"; auto jobj = json::parse(jsonstr); std::cout <<"抽出: " << jobj["person"] << endl; }
実際に文字列をオブジェクトに変換するのはこちらの1行のみ!!
auto jobj = json::parse(jsonstr);
これで変換OK!!とても簡単でした。
jsonオブジェクトから各種要素を取得する場合には、
jobj["str"] jobj["person"]
といったように指定すればOKです。
またjsonオブジェクトに値を代入することも可能です。
例えばこんな感じに。
cout << jobj["str"] << endl; // こんにちは jobj["str"] = "Hello"; cout << jobj["str"] << endl; // Hello
■jsonオブジェクトを文字列に変換
今度は逆にjsonオブジェクトを文字列に変換してみます。
コードはこちら。
#include <iostream> #include "json.hpp" void main(){ std::string jsonstr = R"({ "str":"こんにちは", "boolian":false, "person":[ { "name":"Taro", "age":20 }, { "name":"Tom", "age":30 } ] })"; auto jobj = json::parse(jsonstr); std::cout <<"文字列変換: " << jobj.dump() << endl;
文字列には.dump()関数を用いればよいです。
ということで、
auto jobj = json::parse(jsonstr); std::cout <<"文字列変換: " << jobj.dump() << endl;
のコードにて、jsonオブジェクト変換後、オブジェクトを文字列に変換しているコードになります。
■jsonファイルからjsonデータを読み出し・取り扱い
こちらのjsonオブジェクト変換コードとファイル読み出しを用いればjsonデータを簡単に取り扱うことが出来ます。
例えばjsonファイル内のデータをこちらとした時に、
{"person":{"name":"brown","age":30,"message":"Hello"}}
こちらのようなコードを作成すればファイル内のjson要素の取得が可能になります。
#include <iostream> #include <fstream> #include <string> #include "json.hpp" void main(){ ifstream ifs("./file.json"); std::string jsonstr; if(ifs.fail()){ cout << "File Open Error" << endl; return -1; } while(getline(ifs, jsonstr)){ cout<<"[Read result] "<<str<<endl; } auto jobj = json::parse(jsonstr); std::cout <<"抽出: " << jobj["person"] << endl; }
ライブラリを用いることで簡単にjsonデータの取り扱いが出来ますね!!
■ビルド時のwarning対応
note: parameter passing for argument of type ‘__gnu_cxx::__normal_iterator<const nlohmann::basic_json<>*, std::vector<nlohmann::basic_json<>, std::allocator<nlohmann::basic_json<> > > >’ changed in GCC 7.1
といったwarningが出てしまうかもしれません。
まぁwarningですし出ても実行には支障は出ないのですが、、、
少し気味が悪い。。恐らくGCCのバージョンが原因なんだろうけど。。
ということで理由を調査してみました!!
すでにIssueとして上げられておりました!!
https://github.com/nlohmann/json/issues/1861
やはりバージョンに起因したものだったようです。
どうやら作成されたライブラリがバージョン6以前で作成されたことが要因のようです。
バージョン7.1以降でビルドを実行している限りwarningは無視することが出来るよう。
こちらのオプションを付ければwarningが出力されなくなるので利用sるうことが勧められておりました。
-Wno-psabi -Wall -Wextra -pedantic
確かにこちらのオプションを付ければwarningは出て来なくなりました。
とりあえずこちらの方法を採用することにします。