2

std::istream1つのオブジェクトとして表示する必要があるオブジェクトのリストがありstd::istreamます。したがって、A、B、および C の 3 つの s がある場合、最初に A からのバイトを返し、次に B からのバイトを返し、次に C に到達する前に Distreamを作成できるようにしたいと考えています。複合ストリームは常に順次読み取られ、すべてのバイトが読み取られた後に閉じられます。istreamEOF

stl/boost を使用してこれを行う簡単な方法はありますか?それとも、独自の複合 istream を作成する必要があるだけですか?

4

1 に答える 1

1

別の質問 ( https://stackoverflow.com/a/17103292/1424877 ) に対するトピック外の回答が役立つ場合があります。

#include <iostream>
#include <string>
#include <sstream>

class ConcatStreams : public std::streambuf
{
    int useBuf;
    std::streambuf *sbuf_[2];
    char buffer_[1024];

  public:
    ConcatStreams(std::istream& sbuf1, std::istream& sbuf2) :
        useBuf(0), sbuf_{sbuf1.rdbuf(), sbuf2.rdbuf()}
    { }

    int underflow()
    {
        if (this->gptr() == this->egptr()) {
            std::streamsize size = 0;
            while (useBuf < 2) {
                size = this->sbuf_[useBuf]->sgetn(this->buffer_, sizeof this->buffer_);
                if (!size) {
                    useBuf++;
                } else {
                    break;
                }
            } 
            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());
    }
};

int main()
{
    std::istringstream is("hello world!\n");

    ConcatStreams cs_(is, std::cin); // prepend "hello world" to the input
    std::istream cs(&cs_);

    std::string s;
    while (cs >> s)
      std::cout << "'" << s << "'" << std::endl;
}

std::cinこの特定のトリックを使用して、それ自体、またはそれ自体と連結することはできないことに注意してくださいisただし、2 つの異なる入力ストリームを連結することは問題なく機能するはずです。複数のインスタンスを連結することもできConcatStreamsます!

于 2013-10-22T22:48:54.887 に答える