2017/08/23

[c/c++]設定ファイルを読みたい

プログラムを作っていて、設定ファイルを使いたいことがある。
引数に設定してもよいのだが、個数が多かったり、同じ設定を何度も使うことになったりすると、どうせなら設定ファイルにしてしまいたいのだ。


Linuxには、これといった設定ファイルの書式がなさそうではあるが、だいたいはこんな感じだと思う。

  • 項目=設定値
  • コメント行は#
  • =の前後にスペースがあったり、空行があってもOK


「項目=設定値」だけであれば、こんな感じのことをやっていけば読込むことができる。

char name[32 + 1];
fscanf(fp, "name=%32s\n", name);

(\0は%32sの中に入るんだっけ・・・)

しかし、こんなのをゴリゴリとコーディングしていくのも面倒だ。
それに、これだとスペースや改行を処理することができないので、割り切ってしまえばよいものの、なんか、ねぇ。

また、そういうのを自作したいわけでもない。


ネットで「linux 設定ファイル 編集」なんて検索しても、期待するものが見つからない。。。
ようやく見つけたのが、こちら。

benhoyt/inih: Simple .INI file parser in C, good for embedded systems

iniファイルのパーサーだそうな。
セクションを[]でわけるし、コメントは「;」だけど、コメントはINI_INLINE_COMMENT_PREFIXESで変更できるらしい。
READMEに載っているサンプルで読込んでいるtest.iniは[protocol]と[user]というセクションがあるけれども、がなくても使えるのではなかろうか?


まずは、ライブラリを作る。

$ git clone https://github.com/benhoyt/inih.git
$ cd inih/extra
$ make -f Makefile.static
$ cd ../examples
$ gcc -o tst ini_example.c -L../extra -linih
$ ./tst
Config loaded from 'test.ini': version=6, name=Bob Smith, email=bob@smith.com

うん、シンプルでよいじゃないか!


では、test.iniのコメントを#にして、カテゴリーを削除したファイルではどうなるか・・・。
うーん、エラーにならず、変な値が読み取れてしまった。

サンプルソースを見ると、handler()の中でsectionを比較するようになっていた。
MATCH()マクロからsection比較している部分をなくすと、読み込めるようになった。

よしよし。


最後に、#をコメントにしたMakefileを載せておこう。

https://gist.github.com/hirokuma/a2c4bab70d43db8ddf17b1a673da1b3e

Makefileでgccの文字列マクロを設定するときって、こうやるのね。。。
#もエスケープせんといかんのは、盲点だった。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。