« 2005年09月 | メイン | 2005年11月 »

2005年10月07日

書き残しておきたいのでここに記す C++ STL map 連想配列 ネスト

寝ようとしたらアイデアが閃く法則って何でしょうか。
私を寝かせないための陰謀ですか?
書き留めておかないと絶対忘れてしまうのでとにかくここに記す。
map<string, map<string, string> > conf;
で良いのではないかと思ったのですが、何故か上手く行かなかったので代替手段。
仮に上手く行ったらそっちの方が単純でわかりやすいと思うのでそっち使います。

STL <map> をネストさせるやり方

前置き

コンフィグファイルを読み込む場合を想定。フォーマットは

[conf2]
value1 = "foo";
value2 = 38;


こんな感じで。
map<string,string> conf1,conf2;
で、それぞれ独立に読み込む方法が一番単純。
でも、conf3,conf4と増やしていった場合に面倒になります。

方法

map< string, map<string,string> * > conf;
map< string, string> * section;

(本来はファイルから読み込んで……って処理が必要な所ですがどっちみち結果は同じなのでとりあえず)
section = new map< string, string>;

conf.insert(map< string, map< string, string> * >::value_type("conf1",section);

section->insert(map< string, string>::value_type("value1","data"));
section->insert(map< string, string>::value_type("value2","data"));

section = new map< string, string>;

conf.insert(map< string, map< string, string> * >::value_type("conf2",section);

insert(map< string, string>::value_type("value1","data"));
insert(map< string, string>::value_type("value2","data"));

これで格納はOK。
実際に読み込む場合は、例えば以下のような形で読み込んだとすると、

1 :頭一文字目が'['なら新規セクション開始かもしれないフラグを立てる
1-1:読み込んで行って同じ行の中に']'が存在すれば、'[',']'で囲まれた文字列をオブジェクト(string secname)に格納。
1-2:ついでにセクション読み込み中フラグを立てる
2 :セクション読み込み中モードの時にstring = string;の組み合わせがあれば、左辺をstring lv,右辺をstring rvとして読み込み。
2-1:';'以降は全部スキップ。なので行頭に';'を置いたらコメント。

1-1でループ開始。confにセクション名(secname)とそれに使う連想配列領域へのポインタをinsert。
2のループでsection->insertを繰り返して行く。もちろんvalue_type(lv,rv);で。

最終的にnewされた連想配列はsectionの手から離れるので手綱を放したような不気味さがありますが、
conf側で管理しているのでイテレーターを使って一括deleteできるでしょう。多分。

アクセスについては、

(*conf["conf1"])

で参照できます。
キーを指定して値を参照するだけなら、

(*conf["conf1"])["value1"]

ですね。この辺は普通と変わりません。変わると困るんですが。

投稿者 miff : 23:35 | コメント (0)



XREAAD