最近になって std::clog
の存在を知った.「バッファ付き標準エラー出力」だそうな.ってことは std::cout
と std::cerr
と合わせて 3 つの出力先を使い分けられるじゃん.よぅし.
ということで,こんな使い方を提案.
- 目的
-
コマンドライン引数
-v
(verbose の意) が指定された時のみ,ログファイル (verbose.log など) に処理過程のログを出力する.ログとエラーメッセージは別物として扱いたい.こうしたいのは俺だけかねぇ…. - 実装例
-
main()
内部での記述を想定し,必要となる部分だけ書いた.std::string logfile = "/dev/null"; // UNIX 環境の場合 //std::string logfile = "nul"; // Windows 環境の場合 std::ofstream ofsLog; while ((opt = getopt(argc, argv, "v")) != -1) { switch (opt) { case 'v': logfile = "verbose.log"; break; } } ofsLog.open(logfile.c_str()); if (ofsLog.fail()) { std::cerr << "ERROR: can't open log file." << std::endl; } std::clog.rdbuf(ofsLog.rdbuf()); // あとは std::clog << "ログ" << std::endl; std::cerr << "エラーメッセージ" << std::endl; // というように使い分ける. ofsLog.close(); // main() の最後にクローズ
- 実行例
-
上記のような実装を施したプログラムの名前を
logtest
とする.$ ./logtest -v > output.txt 2> error.txt
上記のようにプログラムを実行すれば,実行結果 (たいていは標準出力に出力されるだろう) は output.txt に,エラーメッセージ (たいていは標準エラー出力に出力されるだろう) は error.txt に,ログは verbose.log に,それぞれ書き出される.
ログファイルにもエラーメッセージを書き出したいのであれば,そのようにソースを書き直す必要がある.その場合,同じメッセージをstd::cerr
にもstd::clog
にも書き出すわけだから,ソースの上ではなんかスッキリしない気も.
verbose
フラグなるものを用意して ソースの至る所に if
文を書く よりはスッキリするかなぁと思って書いてみた.バグなどを発見したらぜひご連絡を.
yuuk
使える かもしれない。
研究の最終的なプログラムにはこういう風に
きれいにしておきたいな。
y-iihoshi
そーなんよね.自分でも 「かもしれない」 と思えるレベルの代物.
どの辺りを 「きれい」 と言って頂けているのかは ちょっとピンと来ないんだけども.でも そういう事ばかりに気を取られて研究が進まない,なんて事にはならないよーに.俺みたいに (汗
yuuk
>きれい
あとで使う人(プログラムをいじる人でなく,できたものを利用する人)が
わかりやすい
という意味ぐらいにとってください。(それもおかしな言い方だな)
エラーメッセージとログは一緒じゃ見る気をなくしそうだし。
今作っているプログラムは俺しか使えない。
だってそうしないと終わらん。
y-iihoshi
なるほ.
> だってそうしないと終わらん。
全くです.
y-iihoshi
Windows 環境で /dev/null に相当するものは nul または nul: (但し英字の大小は区別しない) だそうな.
コロンをつけるっつーことは ヌル・ドライブ といったところか.