13

検討:

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.

質問:

  1. stringstream.str(a_value);の違いは何ですか。およびstringstream<<a_value; 具体的には、最初の方法で<<を介した連結が許可されないのに、2番目の方法で連結が許可されるのはなぜですか。

  2. ss_1がs_aとs_bの間に空白を自動的に取得したのはなぜですか?しかし、行***を置き換えることができる行に空白を明示的に追加する必要があり ss_2 << ss_2.str() << " " << s_b;ますか?

4

2 に答える 2

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)に応じて、2 つの異なる方法で動作します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 以降の新しいものであることに注意してください)

詳細については、こちらをご覧ください

追加動作が必要な場合は、 stringstreamwith を作成しios_base::ateます。

std::stringstream ss(std::ios_base::out | std::ios_base::ate)

簡単なサンプルアプリはこちら:

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

上記で説明したように、これは 2 つの異なる方法で出力されます。

hello world
how are you?
hello world
hello worldhow are you?
于 2012-11-26T03:51:36.340 に答える
4

stringstream リファレンスを読むことをお勧めします: http://en.cppreference.com/w/cpp/io/basic_stringstream

std::stringstream::str()基になる文字列の内容を置き換えます

operator<<ストリームにデータを挿入します。

于 2012-11-26T03:37:10.687 に答える