【问题标题】:copying from a std::istreambuf_iterator<> to a std::vector<>从 std::istreambuf_iterator<> 复制到 std::vector<>
【发布时间】:2011-02-23 09:21:54
【问题描述】:

我有一个 Visual Studio 2008 C++ 应用程序,我想将流视为一组迭代器。

例如,如果我要通过流接收 WIN32_FIND_DATA 结构数组,我希望能够执行以下操作:

IStreamBuf< WIN32_FIND_DATA > sb( stream );
std::vector< WIN32_FIND_DATA > buffer;
std::copy( std::istreambuf_iterator< WIN32_FIND_DATA >( &sb ), 
           std::istreambuf_iterator< WIN32_FIND_DATA >(),
           std::back_inserter( buffer ) );

为了实现这一点,我定义了一个派生自 std::basic_streambuf&lt;&gt; 的类:

template< typename T >
class IStreamBuf : public std::basic_streambuf< byte >
{
public:

    IStreamBuf( IStream* stream ) : stream_( stream )
    {        
    };

protected:

    virtual traits_type::int_type underflow()
    {
        DWORD bytes_read = 0;
        HRESULT hr = stream_->Read( &buffer_, sizeof( T ), &bytes_read );
        if( FAILED( hr ) )
            return traits_type::eof();

        traits_type::char_type* begin = 
            reinterpret_cast< traits_type::char_type* >( &buffer_ );
        setg( begin, begin, begin + bytes_read );   
        return traits_type::to_int_type( *gptr() );
    };

private:

    // buffer to hold current item of type T
    T buffer_;

    // stream used to receive data
    IStream* stream_;
}; // class IStreamBuf

我想不通的是如何优雅地从bytes 数组转到WIN32_FIND_DATAs 数组。因为std::basic_streambuf&lt;&gt;需要std::char_traits&lt;&gt;模板参数,我的印象是它只能使用像char或byte这样的内置类型,而不是像WIN32_FIND_DATA这样的结构。正确的?

关于如何进行这项工作的任何建议?

谢谢, 保罗H

【问题讨论】:

    标签: c++ istream streambuf


    【解决方案1】:

    istreambuf_iterator 在缓冲区级别工作,它只是一个字节流。如果你想处理结构,你可能想使用istream_iterator,并创建一个operator&gt;&gt; 来读取WIN32_FIND_DATA 结构。您还可以考虑为WIN32_FIND_DATA 创建/使用代理。

    【讨论】:

    • 我选择std::istreambuf_iterators 的原因是std::istream_iterators 对格式化输入进行操作。因此,我会有一些额外的开销(哨兵对象、流标志检查等)。您能否详细说明“WIN32_FIND_DATA 的代理”的含义。最好是一个小例子?
    • @PaulH:如果你自己从底层缓冲区读取,你只需要处理哨兵对象——使用现有的流读取函数从流中读取不需要哨兵对象。一个示例代理位于:stackoverflow.com/questions/2531874/…
    • 我刚刚尝试使用istream_iterator。它从文件名中过滤掉空白字符。
    • @PaulH:你(可能)想用istream::read 阅读,而不是operator&gt;&gt;。您可以使用your_stream.skipws(false);,但read() 可能更好。
    猜你喜欢
    • 2017-08-04
    • 2011-05-19
    • 1970-01-01
    • 1970-01-01
    • 2014-01-11
    • 2016-03-30
    • 2018-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多