初始化stringstream.str(a_value)和stringstream << a_value之间的差异

use*_*664 13 c++ initialization concatenation stringstream

考虑:

std::string        s_a, s_b;

std::stringstream  ss_1, ss_2;

// at this stage:
//     ss_1 and ss_2 have been used and are now in some strange state
//     s_a and s_b contain non-white space words

ss_1.str( std::string() );
ss_1.clear();

ss_1 << s_a;
ss_1 << s_b;

// ss_1.str().c_str() is now the concatenation of s_a and s_b, 
//                    <strike>with</strike> without space between them

ss_2.str( s_a );
ss_2.clear();

// ss_2.str().c_str() is now s_a

ss_2 << s_b;  // line ***

// ss_2.str().c_str() the value of s_a is over-written by s_b 
// 
// Replacing line *** above with "ss_2 << ss_2.str() << " " << s_b;"
//                    results in ss_2 having the same content as ss_1.
Run Code Online (Sandbox Code Playgroud)

问题:

  1. stringstream.str(a_value)之间的区别是什么?和stringstream << a_value; 而且,具体来说,为什么第一个不允许通过<<但第二个进行连接?

  2. 为什么ss_1会自动在s_a和fen之间获得空白,但是我们是否需要在行中明确添加可以替换行***的空格: ss_2 << ss_2.str() << " " << s_b;

Ste*_*mer 5

您遇到的问题是,因为std::stringstream默认情况下,构建了ios_base::openmode mode = ios_base::in|ios_base::out它是一个非附加模式。

你感兴趣的输出模式在这里(即:ios_base::openmode mode = ios_base::out

std::basic_stringbuf::str(const std::basic_string<CharT, Traits, Allocator>& s)以两种不同的方式运行,具体取决于openmode

  1. mode & ios_base::ate == false:(即非附加的输出流):

    str将设置pptr() == pbase(),以便后续输出将覆盖从s复制的字符

  2. mode & ios_base::ate == true:(即:附加输出流):

    str将设置pptr() == pbase() + s.size(),以便后续输出将附加到从s复制的最后一个字符

(请注意,此附加模式是c ++ 11以来的新增功能)

可以在此处找到更多详细信息。

如果您想要追加行为,请stringstream使用创建您的行为ios_base::ate

std::stringstream ss(std::ios_base::out | std::ios_base::ate)
Run Code Online (Sandbox Code Playgroud)

简单的示例应用程序在这里:

#include <iostream>
#include <sstream>

void non_appending()
{
    std::stringstream ss;
    std::string s = "hello world";

    ss.str(s);
    std::cout << ss.str() << std::endl;

    ss << "how are you?";
    std::cout << ss.str() << std::endl;
}

void appending()
{
    std::stringstream ss(std::ios_base::out | std::ios_base::ate);
    std::string s = "hello world";

    ss.str(s);
    std::cout << ss.str() << std::endl;

    ss << "how are you?";
    std::cout << ss.str() << std::endl;
}

int main()
{
    non_appending();
    appending();

    exit(0);
}
Run Code Online (Sandbox Code Playgroud)

如上所述,这将以两种不同的方式输出:

hello world
how are you?
hello world
hello worldhow are you?
Run Code Online (Sandbox Code Playgroud)

  • 执行此操作的另一种方法,而不修改“ openmode”,是在插入之前搜索流的末尾。`ss.str(s); ss.seekp(0,std :: ios_base :: end); ss &lt;&lt;“你好吗?”; (2认同)