2011-11-22 16 views
5

Come concatenare due stream di stringhe?concatena lo stringstream in C++

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

L'output è il seguente nei due tentativi:

0xbf8cfd20 
baby0xbf8cfddc 

L'uscita desiderata è babyyou.

risposta

11

dovrebbe essere:

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

stringstream::str restituisce la stringa sottostante nel stringstream.

+0

Naturalmente come accennato in questo caso non è necessario 2 'stringstream's, tuttavia ho assunto che l'esempio dato sia una versione banale di un caso d'uso più complesso. – jli

+0

Ciò creerà una copia dei dati di stringa di b; Penso che l'interrogante stia cercando un modo per evitare di farlo. – JasonDiplomat

1

Basta sostituire a << b con a << b.str()

4

più genericamente iostreams attraverso:

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

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

Questo funziona per filestreams, std :: cin ecc, nonché per stringstream

6

O

a << b.rdbuf(); 

a condizione che il puntatore di ricezione sia o n all'inizio del flusso per evitare di allocare ancora un altro std::string per il contenuto.

6

Non sono necessarie due istanze di std::stringstream. Uno è abbastanza per lo scopo.

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

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

la domanda era "come concatenare STREAMS", le risposte hanno spiegato come concatenare il contenuto dei corsi d'acqua. Qui è una classe che può essere utilizzato per concatenare due iStreams in un istream (file ConcatStreams.h):

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

usarlo:

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

In sostanza la classe utilizza i streambuf di dai flussi passati ad esso per creare un nuovo streambuf che prima legge il primo streambuf e poi legge il secondo streambuf una volta terminato con il primo.