3

単体テストを作成しているため、テスト中のファイル内のコードを変更できません。私がテストしているコードには、プログラムが正しいメッセージを出力していることを確認するためにファイルにリダイレクトしようとしているというメッセージが cout にあります。遅延を引き起こさない別のプログラムで stdout をリダイレクトする方法はありますか? freopen() を試してみましたが、何らかの理由でプログラムがハングします。

4

2 に答える 2

2

を作成して、の streambuf をそれfilebufに置き換えることができます。cout

{
  std::filebuf f;
  f.open("output.txt", std::ios::out);
  std::streambuf* o = std::cout.rdbuf(&f);
  std::cout << "hello" << std::endl;  // endl will flush the stream
  std::cout.rdbuf(o);
}

の元の streambuf を再度復元するcout(または null ポインターに設定する) 必要があります。そうしないと、グローバル ストリームがフラッシュされて破棄されたときにクラッシュする可能性がfilebufあります。

于 2012-06-07T22:40:04.587 に答える
1

「open()」と「dup2()」を使用できます。以下のヘルパーを使用できます。それらの使用方法の例:

void
code_to_test ()
{
    std::cout << "Here we go" << std::endl;
    std::cerr << "Danger danger" << std::endl;
}

run_test(code_to_test);

run_testヘルパーはリダイレクトを呼び出し、テスト コードを実行します。

template <typename TEST> void
run_test (TEST t, bool append = false) {
    flush_output();
    Redirect o(1, "/tmp/test_stdout", append);
    Redirect e(2, "/tmp/test_stderr", append);
    t();
    flush_output();
}

flush_outputヘルパーはストリームをフラッシュします。

void flush_output () {
    fflush(stdout);
    fflush(stderr);
    std::cout.flush();
    std::cerr.flush();
}

クラスは、コンストラクターでのRedirectリダイレクトに影響します。元の記述子をデストラクタに戻します。

class Redirect
{
    int m_what;
    int m_old_what;
public:
    Redirect (int what, std::string where, bool append = false)
        : m_what(what), m_old_what(dup(what)) {
        int flags = O_CREAT|O_WRONLY;
        if (append) flags |= O_APPEND;
        int f = open(where.c_str(), flags, 0660);
        dup2(f, m_what);
        close(f);
    }
    ~Redirect () {
        dup2(m_old_what, m_what);
        close(m_old_what);
    }
};
于 2012-06-07T23:40:35.213 に答える