2016-06-10 57 views
0

一个字符串流用glibc的标准输入输出,我可以换一个memstream标准输出,从而捕获一段代码的输出编译输出到标准输出:交换为COUT

#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); 
} 

我很好奇,如果同样是可能为iostreams。 我天真的尝试不会编译:

#include <iostream> 
#include <string> 
#include <sstream> 

void hw_cc(){ std::cout<<"hello c++ world\n"; } 
int cc_capt(){ 
    using namespace std; 

    stringstream ss; 
    string capt; 

    //std::swap(ss,cout); //<- the compiler doesn't like this 
    hw_cc(); 
    //std::swap(ss,cout); 

    cout<<"Captured: "<<capt<<'\n'; 
} 

int main(int argc, char** argv){ 
    c_capt(); 
    puts("---------------------------------"); 
    cc_capt(); 
    return 0; 
} 
+0

不要垃圾标签! C是一种不同的语言! – Olaf

+3

'std :: cout.rdbuf(ss.rdbuf())',但实际上你会定义'int cc_capt(std :: ostream&)'并传入流。 – user657267

回答

4

可以,但你不换全码流 - 只是流缓冲区。

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"; 
} 

注意,它在这种情况下,我们注意到真正使用自己所有,只是stringbuf它包含的stringstream。如果我们想要,我们可以定义一个basic_stringbuf<char>并直接使用它,而不是定义一个stringstream,只需使用它所包含的stringbuf即可。