объединить поток строк в C ++ - PullRequest
8 голосов
/ 22 ноября 2011

Как объединить два потока строк?

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

Ответы [ 6 ]

13 голосов
/ 22 ноября 2011

Должно быть:

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

stringstream::str возвращает базовую строку в stringstream.

8 голосов
/ 22 ноября 2011

Или

a << b.rdbuf();

при условии, что указатель get находится в начале потока, чтобы избежать выделения еще одного std::string для содержимого.

6 голосов
/ 22 ноября 2011

Вам не нужно два экземпляра std::stringstream.Для этого достаточно одного.

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

std::string s = a.str(); //get the underlying string
5 голосов
/ 22 ноября 2011

Более общий термин для iostreams:

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

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

Это работает для файловых потоков, std :: cin и т. Д., А также для строкового потока

1 голос
/ 14 июня 2013

Вопрос был «как объединить потоки», ответы объяснили, как объединить содержимое потоков. Вот класс, который можно использовать для объединения двух потоков в один поток (файл 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());
 }
};

Чтобы использовать это:

#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, а затем читает второй streambuf после завершения первого.

1 голос
/ 22 ноября 2011

Просто замените a << b на a << b.str()

...