12

テキストをコンソールに出力し、ソースを制御できない関数があるとしますが、それを呼び出すことはできます。例えば

void foo() {
    std::cout<<"hello world"<<std::endl; 
    print_to_console(); // this could be printed from anything
}

関数自体を変更せずに、上記の関数の出力を文字列にリダイレクトすることは可能ですか?

ターミナル経由でこれを行う方法を探していません

4

3 に答える 3

27

はい。それは可能です。ここに小さなデモがあります:

#include <sstream>
#include <iostream>

void print_to_console() {
    std::cout << "Hello from print_to_console()" << std::endl;
}

void foo(){
  std::cout<<"hello world"<<std::endl; 
  print_to_console(); // this could be printed from anything
}
int main()
{
    std::stringstream ss;

    //change the underlying buffer and save the old buffer
    auto old_buf = std::cout.rdbuf(ss.rdbuf()); 

    foo(); //all the std::cout goes to ss

    std::cout.rdbuf(old_buf); //reset

    std::cout << "<redirected-output>\n" 
              << ss.str() 
              << "</redirected-output>" << std::endl;
}

出力:

<redirected-output>
hello world
Hello from print_to_console()
</redirected-output>

オンラインデモを参照してください。

于 2013-10-21T02:59:08.023 に答える
7

@Andreは私の最初の答えのコメントで尋ねました:

printf、puts、write などを使用するとどうなりますか? – アンドレ・コストゥル

についてprintfは、次の解決策を思いつきました。fmemopenは POSIX でのみ使用できるため、POSIX でのみ機能しますが、必要に応じて代わりに一時ファイルを使用できます。移植可能なソリューションが必要な場合は、その方が適しています。基本的な考え方は同じでしょう。

#include <cstdio>

void print_to_console() {
    std::printf( "Hello from print_to_console()\n" );
}

void foo(){
  std::printf("hello world\n");
  print_to_console(); // this could be printed from anything
}

int main()
{
    char buffer[1024];
    auto fp = fmemopen(buffer, 1024, "w");
    if ( !fp ) { std::printf("error"); return 0; }

    auto old = stdout;
    stdout = fp;

    foo(); //all the std::printf goes to buffer (using fp);

    std::fclose(fp);
    stdout = old; //reset

    std::printf("<redirected-output>\n%s</redirected-output>", buffer);
}

出力:

<redirected-output>
hello world
Hello from print_to_console()
</redirected-output>

オンラインデモ

于 2013-10-21T15:44:39.590 に答える