Home> 備忘録: 2005年10月アーカイブ

備忘録: 2005年10月アーカイブ

ログ出力

  • 2005年10月22日 00:23
  • 備忘録

最近になって std::clog の存在を知った.「バッファ付き標準エラー出力」だそうな.ってことは std::coutstd::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 文を書く よりはスッキリするかなぁと思って書いてみた.バグなどを発見したらぜひご連絡を.

  • Comments (Close): 5
  • TrackBack (Close): 1

枝葉末節

  • 2005年10月 1日 00:27
  • 備忘録

コマンドライン引数の解析処理って,長いよね.そう,switch 文を使うからだね.こーんな長いのを,毎回毎回 main() 関数の中に書きたくないよね.できることなら,関数か何かにまとめて,外に出してしまいたいよね.じゃーあ,せっかく C++ で書いてるんだから,1 つのクラスとして作ってみようか.

…………

うん,スッキリしたね.
でも,別のプログラムを新たに作る時って,結局 ほとんどをコピペして switch 文を書き換えるわけだよね.てことは,その書き換える場所が,main() 関数内からクラス実装部に変わっただけだね.同じはずのクラスの実装を,毎度のように書き換えるのって,どうなんだろうね.じゃーあ,せっかく継承とかを輪講で勉強したから,抽象クラスとして作り直してみようか.

…………

うん,随分それっぽくなってきたね.別のプログラムを作る時は,この抽象クラスを継承したクラスを作って,必要なトコだけオーバーライドすれば良いね.
でも,このクラスのインスタンスが複数同時に存在することって,まずないよね.

  • Comments (Close): 3
  • TrackBack (Close): 1

Home> 備忘録: 2005年10月アーカイブ

カテゴリ
アーカイブ
購読
Powerd By

Return to page top