【问题标题】:getting cout output to a std::string将 cout 输出到 std::string
【发布时间】:2011-07-08 18:26:30
【问题描述】:

我有以下cout 声明。我使用 char 数组,因为我必须传递给 vsnprintf 来转换变量参数列表并存储在 Msg 中。

有什么方法可以让cout 输出到 C++ std::string

char Msg[100];
char appname1[100];
char appname2[100];
char appname3[100]; 

// I have some logic in function which some string is assigned to Msg.
std::cout << Msg << " "<< appname1 <<":"<< appname2 << ":" << appname3 << " " << "!" << getpid() <<" " << "~" << pthread_self() << endl;

【问题讨论】:

    标签: c++ cout stdstring


    【解决方案1】:

    您可以将cout 替换为stringstream

    std::stringstream buffer;
    buffer << "Text" << std::endl;
    

    您可以使用buffer.str() 访问该字符串。

    要使用stringstream,您需要使用以下库:

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

    【讨论】:

    • @venkysmarty:您可以在每个字符串之后清除缓冲区。如果字符串用空格或类似的东西分隔,您可以将其拆分。
    • 如何将它与 printf 一起使用?与 cout 不同,显然我不能用缓冲区替换 printf!
    • @Hossein,确实这不适用于printf,在这种情况下你将不得不使用snprintf
    【解决方案2】:

    【讨论】:

    • 您能否简要介绍一下您的解决方案?
    • 接受的答案实际上并不是问题的答案,因为这不是关于将 cout 捕获到字符串:我希望你能写下这个!
    • @campa 也许你应该在一个单独的问题中描述你的问题?目前尚不清楚您要做什么。
    【解决方案3】:

    如果您可以更改代码,请使用 ostringstream(或 stringstream)而不是 cout。

    如果您无法更改代码并想“捕获”正在输出的内容,您可以重定向输出或通过管道传输。

    然后您的进程可能会读取文件或通过共享内存获取管道信息。

    【讨论】:

    • 您能描述一下如何捕获 cout.. 吗?
    【解决方案4】:
    #include <stdio.h>
    
    #include <iostream>
    #include <string>
    #include <sstream>
    
    // This way we won't have to say std::ostringstream or std::cout or std::string...
    using namespace std;
    
    /** Simulates system specific method getpid()... */
    int faux_getpid(){
        return 1234;
    }
    
    /** Simulates system specific method pthread_self()... */
    int faux_pthread_self(){
        return 1111;
    }
    
    int main(int argc, char** argv){
    
        // Create a char[] array of 100 characters...
        // this is the old-fashioned "C" way of storing a "string"
        // of characters..
        char Msg[100];
    
    
        // Try using C++-style std::string rather than char[],
        // which can be overrun, leading to 
        // a segmentation fault.
        string s_appname1; 
    
        // Create old-fashioned char[] array of 100 characters...
        char appname2[100];
    
        // Create old-fashioned char[] array of 100 characters...
        char appname3[100]; 
    
        // Old-fashioned "C" way of copying "Hello" into Msg[] char buffer...
        strcpy(Msg, "Hello");
    
        // C++ way of setting std::string s_appname equal to "Moe"...
        s_appname1 = "Moe";
    
        // Old-fashioned "C" way of copying "Larry" into appname2[] char buffer...
        strcpy(appname2, "Larry");
    
        // Old-fashioned "C" way of copying "Shemp" into appname3[] char buffer...
        strcpy(appname3, "Shemp");
    
        // Declare le_msg to be a std::ostringstream...
        // this allows you to use the C++ "put-to" operator <<
        // but it will "put-to" the string-stream rather than
        // to the terminal or to a file...
        ostringstream le_msg;
    
        // Use put-to operator << to "write" Msg, s_appname1, s_appname2, etc...
        // to the ostringstream...not to the terminal...
        le_msg << Msg << " "<< s_appname1 <<":"<< appname2 << ":" << appname3 << " " << "!" << faux_getpid() <<" " << "~" << faux_pthread_self();
    
        // Print the contents of le_msg to the terminal -- std::cout --
        // using the put-to operator << and using le_msg.str(),
        // which returns a std::string.
        cout << "ONE: le_msg = \"" << le_msg.str() << "\"..." << endl;
    
        // Change contents of appname3 char[] buffer to "Curly"...
        strcpy(appname3, "Curly");
    
        // Clear the contents of std::ostringstream le_msg
        // -- by setting it equal to "" -- so you can re-use it.
        le_msg.str(""); 
    
        // Use put-to operator << to "write" Msg, s_appname1, s_appname2, etc...
        // to the newly cleared ostringstream...not to the terminal...
        // but this time appname3 has been set equal to "Curly"...
        le_msg << Msg << " "<< s_appname1 <<":"<< appname2 << ":" << appname3 << " " << "!" << faux_getpid() <<" " << "~" << faux_pthread_self();
    
        // Print the new contents of le_msg to the terminal using the  
        // put-to operator << and using le_msg.str(),
        // which returns a std::string.
        cout << "TWO: le_msg = \"" << le_msg.str() << "\"..." << endl;
    
        // This time, rather than using put-to operator << to "write"
        // to std::ostringstream le_msg, we'll explicitly set it equal
        // to "That's all Folks!"
        le_msg.str("That's all Folks!");
    
        // Print the new contents of le_msg "That's all Folks!" to  
        // the terminal via le_msg.str()
        cout << "THREE: le_msg = \"" << le_msg.str() << "\"..." << endl;
    
        // Exit main() with system exit value of zero (0), indicating
        // success...
        return 0;
    
    }/* main() */
    

    输出:

    ONE: le_msg = "Hello Moe:Larry:Shemp !1234 ~1111"...
    TWO: le_msg = "Hello Moe:Larry:Curly !1234 ~1111"...
    THREE: le_msg = "That's all, folks!"...
    

    【讨论】: