debug_num_put
昨日のパース関連の続きです。
C++で簡単なパースを行う場合、I/Oストリームの書式付き入出力が便利です。
void func1(std::istream& is) { // 入力例: "123 456" int a, b; is >> a >> b; }
しかし、この方法はストリームに吹き込まれているロケールによって結果が変わってしまいます。
また、
void func2(const char* filename) { std::ifstream is(filename); int a, b; is >> a >> b; }
のようなパターンでもグローバルロケールが吹き込まれるため、よくありません。
「普通」にパースするためには、
void func3(const char* filename) { std::ifstream is(filename); is.imbue(std::locale::classic()); // これが必要 int a, b; is >> a >> b; }
のようにクラシックロケールを明示的に吹き込む必要があります。
こうした意図しないロケールの利用を見つけるために、デバッグ用のnum_get/num_putを作りました。
<hamigaki/debug_facets.hpp>
使い方はmain()関数の先頭などで、
std::locale loc0(std::locale(), new hamigaki::debug_num_get); std::locale loc(loc0, new hamigaki::debug_num_put); std::locale::global(loc);
のようにします。
グローバルロケールを参照して数値の入力が行われるとstd::cerrにメッセージが出力され、数値の出力が行われると数値とともにメッセージが出力されます。
もちろん、本当にロケールに依存した入出力を行いたい場合もメッセージが出力されてしまうわけですが、「うっかり」を見つけ出す役には立つのではないかと思います。