はじめに
C言語でアプリケーションを作成するとき、入出力の基本的な処理からコーディングするのは面倒ですし、バグの温床のなりえます。
良い解決策がないか調べたところ、glib2.0というライブラリが
- インストール・利用の容易さ
- 多機能
- ライセンス
という観点で、良さそうであると思いました。
一方、ネット上にあまり情報がなく、公式ドキュメントもわかりにくいということもあり、本記事にて基本的な使い方を紹介したいと思います。
今回は、confファイルの読み込みについて記載します。
動作環境
本記事は、下記の環境で動作を確認しています。
- Ubuntu18.04
- gcc
インストール手順
下記コマンドでglib2.0一式をインストールすることができます。
Ubuntu18.04の場合、バージョン2.56.4が入るようです。
sudo apt install libglib2.0-dev
使用例
本記事では、下記のような設定ファイルを読み込むことを想定します。
[value]
key1=test
key2=1
key3=1.5
#シャープでコメント
[array]
key4=0.5,1,1.5
key5=true,false,true
上記、設定ファイルを読み込み、読み込み内容を標準出力に表示するソースは下記になります。
#include <glib.h>
int main()
{
int i;
GKeyFile *file;
GError *err = NULL;
gchar *key1_value;
gint key2_value;
gdouble key3_value;
gdouble *key4_array;
gsize key4_array_len;
gboolean *key5_array;
gsize key5_array_len;
//ファイルオブジェクト作成
file = g_key_file_new();
//配列の区切り文字を","に設定
g_key_file_set_list_separator(file, ',');
if (!g_key_file_load_from_file(file, "./keyfile.conf", 0, &err)) {
g_print("failed to load keyfile. msg=%s\n", err->message);
} else {
g_print("success to load keyfile.\n");
if ((NULL == (key1_value = g_key_file_get_string(file, "value", "key1", &err)) && (NULL != err))) {
g_print("failed to parse key1. msg=%s\n", err->message);
} else if ((0 == (key2_value = g_key_file_get_integer(file, "value", "key2", &err)) && (NULL != err))) {
g_print("failed to parse key2. msg=%s\n", err->message);
} else if ((0 == (key3_value = g_key_file_get_double(file, "value", "key3", &err)) && (NULL != err))) {
g_print("failed to parse key3. msg=%s\n", err->message);
} else if ((NULL == (key4_array = g_key_file_get_double_list(file, "array", "key4", &key4_array_len, &err)) && (NULL != err))) {
g_print("failed to parse key4. msg=%s\n", err->message);
} else if ((NULL == (key5_array = g_key_file_get_boolean_list(file, "array", "key5", &key5_array_len, &err)) && (NULL != err))) {
g_print("failed to parse key4. msg=%s\n", err->message);
} else {
g_print("success to parse all keys.\n");
g_print("key1 = %s\n", key1_value);
g_print("key2 = %d\n", key2_value);
g_print("key3 = %f\n", key3_value);
g_print("key4 = ");
for (i = 0; i < key4_array_len; i++) {
g_print("%f,", key4_array[i]);
}
g_print("\n");
g_print("key5 = ");
for (i = 0; i < key5_array_len; i++) {
g_print("%s,", key5_array[i] ? "true" : "false");
}
g_print("\n");
//開放処理
g_free(key1_value);
g_free(key4_array);
g_free(key5_array);
g_key_file_free(file);
}
}
if (NULL != err) {
g_error_free(err);
}
return 0;
}
下記のコマンドでコンパイルを行うことができます。
gcc main.c -o main `pkg-config --cflags --libs glib-2.0`
下記のコマンドで実行します。設定ファイルがきちんと読み込めていることが確認できます。
./main
success to load keyfile.
success to parse all keys.
key1 = test
key2 = 1
key3 = 1.500000
key4 = 0.500000,1.000000,1.500000,
key5 = true,false,true,
上記ソースでは、設定ファイルの内容が正しくなかったとき、エラーメッセージを出力するようにしています。
例えば、設定ファイルのkey4の値にkey4=0.5,1,1.5,aa
と小数値の期待に対し、文字列をわざと設定してみます。この状態で再び実行すると、下記のように、aaがfloat値として解釈できない旨を表示してくれます。このようにglibが、エラー要因をわかりやすく表示してくれます。
./main
success to load keyfile.
failed to parse key4. msg=Value ?aa? cannot be interpreted as a float number.
あとがき
C言語は文字列処理のコーディングに向いておらず、入出力の基本的な処理を作るのは骨が折れます。glib2.0を活用することで、本質ではない部分に割く時間を削減し、本当に重要なことに注力できると思います。