C++ 将stringstream交换为cout

C++ 将stringstream交换为cout,c++,iostream,C++,Iostream,使用glibc的stdio,我可以将memstream交换为stdout,从而捕获编译后输出到stdout的代码的输出: #include <stdio.h> void swapfiles(FILE* f0, FILE* f1){ FILE tmp; tmp = *f0; *f0 = *f1; *f1 = tmp; } void hw_c(){ puts("hello c world"); } int c_capt(){ FILE* my_memstream; char

使用glibc的stdio,我可以将memstream交换为stdout,从而捕获编译后输出到stdout的代码的输出:

#include <stdio.h>

void swapfiles(FILE* f0, FILE* f1){ FILE tmp; tmp = *f0; *f0 = *f1; *f1 = tmp; }

void hw_c(){ puts("hello c world"); }

int c_capt(){
  FILE* my_memstream;
  char* buf  = NULL;
  size_t bufsiz = 0;

  if( (my_memstream = open_memstream(&buf, &bufsiz)) == NULL) return 1;

  FILE * oldstdout = stdout;

  swapfiles(stdout, my_memstream);
  hw_c();
  swapfiles(stdout, my_memstream);

  fclose(my_memstream);
  printf("Captured: %s\n", buf);
}

可以,但不交换整个流——只交换流缓冲区

void cc_capt() {
    using namespace std;

    stringstream ss;

    auto orig = std::cout.rdbuf(ss.rdbuf());

    hw_cc();

    std::cout.rdbuf(orig);

    std::cout << "captured: " << ss.str() << "\n";
}
void cc_capt(){
使用名称空间std;
细流ss;
auto-orig=std::cout.rdbuf(ss.rdbuf());
hw_cc();
标准::系数rdbuf(原始);

std::cout可以,但不能交换整个流——只交换流缓冲区

void cc_capt() {
    using namespace std;

    stringstream ss;

    auto orig = std::cout.rdbuf(ss.rdbuf());

    hw_cc();

    std::cout.rdbuf(orig);

    std::cout << "captured: " << ss.str() << "\n";
}
void cc_capt(){
使用名称空间std;
细流ss;
auto-orig=std::cout.rdbuf(ss.rdbuf());
hw_cc();
标准::系数rdbuf(原始);

std::cout基于Jerry的示例,我编写了一个模板,它有一个很大的优点,即安全(即,如果发生异常,您的缓冲区会自动恢复)

这样做:

{
  ostream_to_buf<char> buf(std::cout);

  ... run code which `std::cout << "data"` ...

  std::string const output(buf.str());

  ... do something with `output` ...
}  // <-- here the buffer is restored
复制构造函数和赋值运算符将被删除,因为它们在这种情况下不起作用


您可能可以使用C++11甚至C++03来实现它。我有C++14,但我认为这些都不需要C++14。

基于Jerry的示例,我编写了一个模板,它有一个很大的优点,即安全性(即,如果发生异常,您的缓冲区会自动恢复)

这样做:

{
  ostream_to_buf<char> buf(std::cout);

  ... run code which `std::cout << "data"` ...

  std::string const output(buf.str());

  ... do something with `output` ...
}  // <-- here the buffer is restored
复制构造函数和赋值运算符将被删除,因为它们在这种情况下不起作用


您可能可以使用C++11甚至C++03来实现它。我有C++14,但我认为这些都不需要C++14。

不要垃圾标签!C是另一种语言!
std::cout.rdbuf(ss.rdbuf())
,但实际上您需要定义
int cc_capt(std::ostream&)
并将流传入。@user657267,如果您没有访问所有函数的权限(例如
cc_hw()
),那么捕获
std::cout
是一种非常好的方法。我在一些单元测试中这样做,其中某些函数只在控制台中打印消息。不要垃圾邮件标签!C是另一种语言!
std::cout.rdbuf(ss.rdbuf())
,但实际上,如果您不能访问所有函数(如
cc_-capt()
),您需要定义
int cc_-capt(std::ostream&)
,并将流传入。@user657267然后捕获std::cout
是一种非常好的方法。我在一些单元测试中这样做,其中某些函数只是在控制台中打印消息。