質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.77%

標準入出力を使ったプログラムのデバッグを皆さんはどうしているのでしょう?

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 5,234

score 6561

例えば、下記のプログラムは標準入力(std::cin)からテキストファイルを読み込み行番号を付けて標準出力(std::cout)に出力するものですが、この様なプログラムをデバッグする場合どのようにするのがいいのでしょうか?

//
#include <iostream>
#include <string>
#include <iomanip>
//
using namespace std;
//
int main(void)
{
    int lno= 0;
    string iStr;
    //
    while(getline(cin,iStr)){
        cout << setw(4) << ++lno << ' ' << iStr << endl;
    }
    //
    return 0;
}


「環境」
FreeBSD 11.1-RELEASE-p1
clang version 4.0.0
CodeLite(IDE)

今までファイルの入出力などは使っていましたが標準入出力を使った(デバッグ)経験は皆無です。で、
・エラー出力(std::cerr)で表示して確認する。
・fprintf()などを入れてファイルで結果を確認する。
などは考えたのですが、もう少しマシな(やりやすい)方法があればご教授いただきたいのですが。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+1

こんにちは。

私はあまりstd::cerrは所謂printfデバッグには使わないです。
Windowsではstd::cerrはバッファリングされないためstd::coutと同期がとれず必要な情報を取るのが意外に難しいからです。

短命なプログラムのデバッグ時は、std::coutへデバッグ出力も出し、ターゲットの出力とデバッグ用出力を区別できるようデバッグ出力側を[]で囲う等の工夫をしてます。
長命なプログラムの場合は真面目にログ出力を作ってそこに出します。リリース後もログを出力できるようにしておけば、客先でのトラブル対策も可能になりますし。

ついでに、ログ・レベルを指定できるロガーって多いのですが、色々トライした結果、ログ・レベルの指定はしません。お客様環境でログ・レベルの指定を変更しつつログを取るなんて事実上不可能ですし、自分でデバッグする場合も結局全部出力してデバッグすることがほとんどなので。ただし、後から解析しやすいよう、ログの種類毎に決まったマーカー文字列を付けておきます。これにより、grepするときれいに分かれます。一緒にスレッドIDも出しておくとマルチスレッド、マルチプロセスなシステムのデバッグもやりやすくなります。

また、ログの行ヘッダ部をカンマ区切りしておくと、Excel等で解析しやすいので意外に便利な時もあります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/02 12:40

    FYI: Windows環境に限らず std::cerr はバッファリング無しが既定動作ですね。https://cpprefjp.github.io/reference/iostream/cerr.html

    キャンセル

  • 2017/09/02 13:11

    なるほど。これは標準動作だったのですね。
    そんな気もしてたのですが、ちょっと自信がなくて。
    ありがとうです。

    キャンセル

  • 2017/09/02 19:16

    >ヘッダ部をカンマ区切りしておくと、Excel等〜
    なるほど、これは気がつきませんでした^^; ありがとうございます

    キャンセル

  • 2017/09/02 19:35

    皆さん色々案を出して頂いてありがとうございます。プログラム自体が小さい(1秒程度で終了w)のでやっぱり#ifdef & coutでやっていこうと思います。

    キャンセル

+1

普通に、コマンドラインでリダイレクトやパイプを使って動かしてみる、というのは駄目なのでしょうか。IDE から実行できないと駄目とかなのかな。
デバッグするプログラムをコンパイルしてできた実行ファイルが prog として、

$ ./prog < test.txt


みたいな。

そういう話ではなくて、このようにテストをするとして、デバッグ用情報の print をどのように実行して、どのように拾うか、という話でしょうか。

標準エラーにデバッグ情報を吐き出すというのは「まとも」な方法です。prog のコマンドラインオプションとしてデバッグフラグやデバッグレベルを制御できるものを用意し、それに応じて標準エラーに情報を吐き出すのは「まとも」なコマンドでもよくあります。開発中のデバッグだけでなく、運用時の不具合調査のためにも役立つ詳細情報なら、コマンドラインオプションを指定すれば出力できるようにプログラムを作っておくのも悪くありません。
コマンドラインオプションの例を以下に示します。

$ ./prog --verbose   # 冗長モード
$ ./prog -v          # 冗長モード
$ ./prog -vv         # もっと冗長モード 
$ ./prog -vvv        # もっともっと冗長モード
$ ./prog -d          # デバッグモード
$ ./prog --debug     # デバッグモード
$ ./prog --debug=3   # デバッグレベル指定

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/02 19:25 編集

    リンク時にうまく行かないときなど、-vのパラメータはよく出てきますd^^ 今回のプログラムは私用で作っている物(高々2000行程度)なので“デバッグ処理を埋め込みたくない”ということもありますので通常のcoutでやっていきたいと思います。有難うございました、今後の参考にさせていただきます。 

    キャンセル

  • 2017/09/02 19:39

    申し遅れました、IDEは得に考えていません。多分パイプからデータ受け取って加工するプログラムに付いてはIDEでは難しいと思いますので。

    キャンセル

  • 2017/09/02 21:00

    質問内容からは技術レベルがわからなかったのでこんな回答にしましたが、C++ なんてここ 20 年触っていない私がちゃちゃを入れることもなかったみたいで。

    キャンセル

0

C++で応用できるかわかりませんが、Cの場合でファイル入出力までできているならば、ファイルポインタをstdin/stdoutに変更すれば読み込み元/書き込み先をファイルから標準入出力に変更できます。

後は少しだけ条件分岐を追加するとかマクロでコンパイル時切り替えすれば、デバッグ時だけファイル入出力にするということができます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/02 19:20 編集

    ありがとうございます。質問する前の話ですが、私の無知で、ifstream inFile(cin);などとして失敗しました;; クラスを作るときにコンストラクタのパラメタとして入力ファイルを渡しているので、これが出きると楽なんですが・・・

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.77%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る