デフォルトでは、ヘッダーが含まれる C++ アプリケーションでは、cin、cout、cerr、およびclogの 4 つのストリーム オブジェクトがインスタンス化されます(対応するワイド文字型もインスタンス化されます)。
デフォルトでは、 cinは標準入力デバイス (通常はキーボード) に接続され、cout、cerr、clogは標準出力デバイス (通常はコンソール) に接続されます。
私の質問は、これらの事前定義されたストリーム オブジェクトが接続されているデバイスを変更する方法です。
次のようなヘルパー クラスを使用できます。
class RedirectOutput
{
std::ostream &os_;
std::filebuf f_;
std::streambuf *obuf_;
RedirectOutput (const RedirectOutput &); // disallow
void operator = (const RedirectOutput &); // disallow
public:
RedirectOutput (std::ostream &os,
std::string where,
std::ios::openmode mode = std::ios::out)
: os_(os.flush()) {
f_.open(where.c_str(), mode);
obuf_ = os.rdbuf(&f_);
}
~RedirectOutput () {
os_.flush();
os_.rdbuf(obuf_);
}
};
そして、次のように使用します。
{
RedirectOutput ro(std::cout, "output.txt");
std::cout << "Hello" << std::endl;
}
std::cout << "Goodbye" << std::endl;
Hello
ファイルoutput.txt
にGoodbye
移動し、端末に移動します。
はい、可能です。OS に依存しません。cout
ファイルへの書き込みをリダイレクトする簡単なデモを次に示します。
#include <iostream>
#include <fstream>
int main() {
// create a file buf, and open it on a file named "your_output.txt":
std::basic_filebuf<char, std::char_traits<char> > b;
b.open("your_output.txt", std::ios_base::out);
// connect `std::cout` to the chosen file via our file_buf:
std::cout.rdbuf(&b);
// write some output (which shouldn't show up on screen.
std::cout << "This is some junk";
return 0;
}
ただし、原則として、これに反対することをお勧めします。一般に、(一例として) ostream への参照をパラメーターとして受け取る関数にコードを移動し、必要に応じて適切な ostream または ofstream を渡す方がはるかにクリーンです。一方、(たとえば) コード化された標準ストリームからの/への読み取り/書き込みが既にある既存のコードの大きな塊がある場合、これにより、すべてを書き直すことなく機能させることができます。
これはオペレーティング システムによって異なりますが、Unix ライクなシステムでは、プログラムの実行中にこれを行うことはできません。プロセスを起動するときに設定する必要があります。
たとえば、zsh
シェルで次のようにプログラムを実行した場合:
./myprogram < file1 > file2 2> file3
...次に、cin
から読み取り、file1
にcout
書き込み、file2
にcerr
書き込みfile3
ます。