【问题标题】:Composite std::istream in C++C++ 中的复合 std::istream
【发布时间】:2013-10-30 15:34:32
【问题描述】:

我有一个 std::istream 对象列表,我需要将其显示为单个 std::istream 对象。因此,如果我有三个istreams、A、B 和 C,我希望能够创建一个istream,D 它将首先返回来自 A 的字节,然后是来自 B 的字节,然后是 C 之前的 EOF到达。复合流将始终按顺序读取,并在读取所有字节后关闭。

是否有使用 stl/boost 的简单方法来执行此操作,还是我只需要编写自己的复合 istream?

【问题讨论】:

  • 查看 Boost.Iostreams。
  • 在您需要从 std::ios 继承之前,我想说最直接的方法是构建一个复合 istream,具有其他流的队列。
  • 您是说您有 std::list 的 istream 吗?含义std::list<std::istream>?
  • 实际上不在 std::list 中,而是在它们的有序集合中。

标签: c++ boost stl iostream


【解决方案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 与自身连接;但它应该可以很好地连接任何两个 不同 输入流。您甚至可以连接多个 ConcatStreams 实例!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-04
    • 1970-01-01
    • 2020-07-13
    • 2012-06-17
    • 2019-06-10
    • 1970-01-01
    相关资源
    最近更新 更多