2011-11-22 7 views
5

Jak mogę połączyć dwa strumienie stringów?Łączenie strumienia ciągu w 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; 
} 

wyjście jest po obu próbach:

0xbf8cfd20 
baby0xbf8cfddc 

żądana jest babyyou.

Odpowiedz

11

Powinno być:

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

stringstream::str zwraca podstawowy ciąg w stringstream.

+0

Oczywiście, jak wspomniano, nie potrzebujesz w tym przypadku 2 'stringstream's, jednak założyłem, że podany przykład jest banalną wersją bardziej złożonego przypadku użycia. – jli

+0

Spowoduje to utworzenie kopii danych łańcuchowych b; Myślę, że pytający może szukać sposobu uniknięcia tego. – JasonDiplomat

4

Bardziej ogólnie całej iostreams:

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

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

Działa to dla filestreams, std :: cin itd., Jak również dla stringstream

6

Albo

a << b.rdbuf(); 

pod warunkiem, że otrzymasz wskaźnik o n na początku strumienia, aby uniknąć przydzielania kolejnego elementu dla treści.

6

Nie potrzebujesz dwóch instancji std::stringstream. Jeden wystarcza do tego celu.

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

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

Pytanie brzmiało: „Jak łączyć strumienie”, odpowiedzi wyjaśniono, jak łączyć zawartość strumieni. Tutaj jest klasa, która może być używana do łączenia dwóch iStreams w jednym istream (ConcatStreams.h pliku):

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

Aby go użyć:

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

Zasadniczo klasa wykorzystuje streambuf jest z potoków przeszły do tego, aby utworzyć nową linię, która najpierw odczytuje pierwszą linię, a następnie odczytuje drugą linię, kiedy kończy się pierwsza.