0

デフォルトでは、ヘッダーが含まれる C++ アプリケーションでは、cin、cout、cerr、およびclogの 4 つのストリーム オブジェクトがインスタンス化されます(対応するワイド文字型もインスタンス化されます)。

デフォルトでは、 cinは標準入力デバイス (通常はキーボード) に接続され、cout、cerrclogは標準出力デバイス (通常はコンソール) に接続されます。

私の質問は、これらの事前定義されたストリーム オブジェクトが接続されているデバイスを変更する方法です。

4

3 に答える 3

2

次のようなヘルパー クラスを使用できます。

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.txtGoodbye移動し、端末に移動します。

于 2012-07-12T05:24:13.863 に答える
2

はい、可能です。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 を渡す方がはるかにクリーンです。一方、(たとえば) コード化された標準ストリームからの/への読み取り/書き込みが既にある既存のコードの大きな塊がある場合、これにより、すべてを書き直すことなく機能させることができます。

于 2012-07-12T05:24:30.203 に答える
1

これはオペレーティング システムによって異なりますが、Unix ライクなシステムでは、プログラムの実行中にこれを行うことはできません。プロセスを起動するときに設定する必要があります。

たとえば、zshシェルで次のようにプログラムを実行した場合:

./myprogram < file1  > file2  2> file3

...次に、cinから読み取り、file1cout書き込み、file2cerr書き込みfile3ます。

于 2012-07-12T04:56:19.580 に答える