2011-11-22 25 views
5

2つのストリングストリームをどのように連結できますか?C++のstringstreamを連結

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <iostream> 
#include <fstream> 
#include <sstream> 
#include <string> 
#include "types.h"  

int main() { 
    char dest[1020] = "you"; 
    char source[7] = "baby"; 
    stringstream a,b; 
    a << source; 
    b << dest; 
    a << b; /*HERE NEED CONCATENATE*/ 
    cout << a << endl; 
    cout << a.str() << endl; 
    return 0; 
} 

出力は、両方の試行で次である:

0xbf8cfd20 
baby0xbf8cfddc 

所望の出力がbabyyouあります。

答えて

11

は次のようになります。

b << dest; 
a << b.str(); 

stringstreamで根本的な文字列を返しますstringstream::str

+0

もちろん、この場合は2つの 'stringstream'は必要ありませんが、私は与えられた例がより複雑なユースケースの簡単なバージョンであると仮定しました。 – jli

+0

これは、bの文字列データのコピーを作成します。私は質問者がそれを避ける方法を探しているかもしれないと思う。 – JasonDiplomat

1

ただ、一般的に全体の入出力ストリームa << b.str()

4

詳細にa << bを置き換える:

std::istream is1, is2; // eg. (i)stringstream 
std::ostream os;  // eg. (o)stringstream 

os << is1.rdbuf(); 
os << is2.rdbuf(); 
os << std::flush; 

これは、ファイルストリームのために働く、STD :: CINなどなどにstringstream

6

それとも

a << b.rdbuf(); 
のために

ただし、getポインタはoです。ストリームの先頭には、コンテンツのためにさらに別のstd::stringを割り当てないようにします。

6

std::stringstreamという2つのインスタンスは必要ありません。 1つは目的のために十分です。

std::stringstream a; 
a << source << dest; 

std::string s = a.str(); //get the underlying string 
1

「ストリームをどのように連結するか」という質問は、ストリームの内容を連結する方法を説明しました。これを使用するに

class ConcatStreams 
: public std::streambuf { 
std::streambuf* sbuf1_; 
std::streambuf* sbuf2_; 
char*   buffer_; 
int useBuf; 
int bufSize; 
public: 
ConcatStreams(std::streambuf* sbuf1, std::streambuf* sbuf2) 
    : bufSize(1024), sbuf1_(sbuf1), sbuf2_(sbuf2), buffer_(new char[bufSize]), useBuf(1) { 
} 
ConcatStreams(const ConcatStreams& orig); 
virtual ~ConcatStreams() { delete[] this->buffer_; } 
int underflow() { 
    if (this->gptr() == this->egptr()) { 
     // get data into buffer_, obtaining its input from 
     // this->sbuf_; if necessary resize buffer 
     // if no more characters are available, size == 0. 
     std::streamsize size=0; 
     if(useBuf==1) { 
      size = this->sbuf1_->sgetn(this->buffer_, bufSize); 
      if(!size) { useBuf++;} 
     } 
     if(useBuf==2) { 
      size = this->sbuf2_->sgetn(this->buffer_, bufSize); 
      if(!size) { useBuf++;} 
     } 
     this->setg(this->buffer_, this->buffer_, this->buffer_ + size); 
    } 
    return this->gptr() == this->egptr() 
     ? std::char_traits<char>::eof() 
     : std::char_traits<char>::to_int_type(*this->gptr()); 
} 
}; 

:ここで1はistream(ファイルConcatStreams.h)に2 istreamsを連結するために使用するクラスがある

#include "ConcatStreams.h" 
istringstream msgIn1("this is a stream."); 
istringstream msgIn2("this is another stream."); 
ConcatStreams cs(msgIn1.rdbuf(), msgIn2.rdbuf()); 
istream msgIn(&cs); 
cout << "'" << msgIn.rdbuf() << "'" << endl; 

基本的にクラスが渡されたストリームからのストリームバッファ年代を使用しています新しいstreambufを作成し、最初に最初のstreambufを読み取り、最初のstreambufを終了すると2番目のstreambufを読み込みます。