C++ 读取向量<;char>;如溪流

C++ 读取向量<;char>;如溪流,c++,stl,C++,Stl,我有一个常量向量,但需要一个函数来读取它。问题是,函数需要一个istream 将向量中的数据传递到此函数的最有效方法是什么 我尝试了这种方法来防止复制流,但它不起作用,因为我的向量是const,而pubsetbuf需要一个非const char* istringstream is; const vector<char>& data = GETDATA(); is.rdbuf()->pubsetbuf(&data[0], data.size()); istrin

我有一个常量向量,但需要一个函数来读取它。问题是,函数需要一个istream

将向量中的数据传递到此函数的最有效方法是什么

我尝试了这种方法来防止复制流,但它不起作用,因为我的向量是const,而pubsetbuf需要一个非const char*

istringstream is;
const vector<char>& data = GETDATA();
is.rdbuf()->pubsetbuf(&data[0], data.size());
istringstream是;
const vector&data=GETDATA();
is.rdbuf()->pubsetbuf(&data[0],data.size());
由于流是只读的,我可以强制转换指针。安全吗? 或者有更好的方法吗?

考虑使用:

#包括
#包括
使用名称空间boost::iostreams;
流bs(data.data(),data.size());
std::istream&is=bs;

您可以编写自己的流:

#include <algorithm>
#include <ostream>

// BasicSequenceInputBuffer
// ============================================================================

template < typename Char, typename Traits = std::char_traits<Char> >
class BasicSequenceInputBuffer
:   public std::basic_streambuf<Char, Traits>
{
    // Types
    // =====

    private:
    typedef std::basic_streambuf<Char, Traits> Base;

    public:
    typedef typename Base::char_type char_type;
    typedef typename Base::int_type int_type;
    typedef typename Base::pos_type pos_type;
    typedef typename Base::off_type off_type;
    typedef typename Base::traits_type traits_type;
    typedef const char_type* pointer;
    typedef std::size_t size_type;

    // Construction
    // ============

    public:
    BasicSequenceInputBuffer(pointer data, size_type size) {
        // These casts are safe (no modification will take place):
        char* begin = const_cast<char_type*>(data);
        char* end = const_cast<char_type*>(data + size);
        this->setg(begin, begin, end);
    }

    // Stream Buffer Interface
    // =======================

    protected:
    virtual std::streamsize showmanyc();
    virtual std::streamsize xsgetn(char_type*, std::streamsize);
    virtual int_type pbackfail(int_type);

    // Utilities
    // =========

    protected:
    int_type eof() { return traits_type::eof(); }
    bool is_eof(int_type ch) { return ch == eof(); }
};


// Get Area
// ========

template <typename Char, typename Traits>
std::streamsize
BasicSequenceInputBuffer<Char, Traits>::showmanyc() {
    return this->egptr() - this->gptr();
}

template <typename Char, typename Traits>
std::streamsize
BasicSequenceInputBuffer<Char, Traits>::xsgetn(char_type* p, std::streamsize n) {
    std::streamsize result = std::min(n, this->egptr() - this->gptr());
    std::copy(this->gptr(), this->gptr() + result, p);
    this->gbump(result);
    return result;
}

template <typename Char, typename Traits>
typename BasicSequenceInputBuffer<Char, Traits>::int_type
BasicSequenceInputBuffer<Char, Traits>::pbackfail(int_type ch) {
    if(is_eof(ch)) {
        if(this->eback() != this->gptr()) {
            this->gbump(-1);
            return traits_type::to_int_type(*this->gptr());
        }
    }
    return eof();
}

typedef BasicSequenceInputBuffer<char> SequenceInputBuffer;


// BasicSequenceInputStream
//=============================================================================

template < typename Char, typename Traits = std::char_traits<Char> >
class BasicSequenceInputStream
:   public std::basic_istream<Char, Traits>
{
    private:
    typedef std::basic_istream<Char, Traits> Base;

    public:
    typedef typename Base::char_type char_type;
    typedef typename Base::int_type int_type;
    typedef typename Base::pos_type pos_type;
    typedef typename Base::off_type off_type;
    typedef typename Base::traits_type traits_type;

    private:
    typedef BasicSequenceInputBuffer<Char, Traits> buffer_type;

    public:
    typedef typename buffer_type::pointer pointer;
    typedef typename buffer_type::size_type size_type;

    // Construction
    // ============

    public:
    explicit BasicSequenceInputStream(pointer data, size_type size)
    :   Base(&m_buf), m_buf(data, size)
    {}

    private:
    buffer_type m_buf;
};

typedef BasicSequenceInputStream<char> SequenceInputStream;


// Test
// ====

#include <iostream>
#include <vector>

int main()
{
    const std::string s = "Hello World";
    const std::vector<char> vector(s.begin(), s.end());
    SequenceInputStream stream(vector.data(), vector.size());

    std::string line;
    std::getline(stream, line);
    std::cout << line << '\n';
}
#包括
#包括
//基本序列输入缓冲区
// ============================================================================
模板
类BasicSequenceInputBuffer
:public std::basic_streambuf
{
//类型
// =====
私人:
typedef std::基本流基;
公众:
typedef typename Base::char\u type char\u type;
typedef typename Base::int_type int_type;
typedef typename Base::pos_type pos_type;
typedef typename Base::off_type off_type;
typedef typename Base::traits\u type traits\u type;
typedef const char_type*指针;
typedef std::size\u t size\u type;
//建筑
// ============
公众:
BasicSequenceInputBuffer(指针数据、大小\类型大小){
//这些类型转换是安全的(不会进行任何修改):
char*begin=const_cast(数据);
char*end=const_cast(数据+大小);
此->设置(开始、开始、结束);
}
//流缓冲接口
// =======================
受保护的:
虚拟std::streamsize showmanyc();
虚拟std::streamsize xsgetn(字符类型*,std::streamsize);
虚拟int_类型pbackfail(int_类型);
//公用事业
// =========
受保护的:
int_type eof(){return traits_type::eof();}
bool是_eof(int_type ch){return ch==eof();}
};
//获取区域
// ========
模板
std::streamsize
BasicSequenceInputBuffer::showmanyc(){
返回this->egptr()-this->gptr();
}
模板
std::streamsize
BasicSequenceInputBuffer::xsgetn(字符类型*p,标准::流大小n){
std::streamsize result=std::min(n,this->egptr()-this->gptr());
std::copy(this->gptr(),this->gptr()+结果,p);
此->gbump(结果);
返回结果;
}
模板
typename BasicSequenceInputBuffer::int\u类型
BasicSequenceInputBuffer::pbackfail(int\u类型ch){
if(is_eof(ch)){
如果(this->eback()!=this->gptr()){
这->gbump(-1);
返回字符类型::到字符类型(*this->gptr());
}
}
返回eof();
}
typedef BasicSequenceInputBuffer SequenceInputBuffer;
//基本序列输入流
//=============================================================================
模板
类BasicSequenceInputStream
:公共标准::基本信息流
{
私人:
typedef std::basic_istream Base;
公众:
typedef typename Base::char\u type char\u type;
typedef typename Base::int_type int_type;
typedef typename Base::pos_type pos_type;
typedef typename Base::off_type off_type;
typedef typename Base::traits\u type traits\u type;
私人:
类型定义基本顺序输入缓冲区类型;
公众:
typedef typename buffer_type::pointer指针;
typedef typename buffer_type::size_type size_type;
//建筑
// ============
公众:
显式BasicSequenceInputStream(指针数据,大小\类型大小)
:基准(&m_-buf),m_-buf(数据,大小)
{}
私人:
缓冲区类型m_buf;
};
typedef BasicSequenceInputStream SequenceInputStream;
//试验
// ====
#包括
#包括
int main()
{
const std::string s=“Hello World”;
常量std::向量向量(s.begin(),s.end());
SequenceInputStream流(vector.data(),vector.size());
std::字符串行;
std::getline(流,行);

std::cout@luk32不,这是为了工作:(我感谢你在回答中所做的努力。但我想我只复制向量。@NeilKirk注意:这里没有复制(序列的开始和结束存储在现有的流指针中)。但是如果内存(大小)没有问题,那么纯拷贝是合理和足够好的。
#include <algorithm>
#include <ostream>

// BasicSequenceInputBuffer
// ============================================================================

template < typename Char, typename Traits = std::char_traits<Char> >
class BasicSequenceInputBuffer
:   public std::basic_streambuf<Char, Traits>
{
    // Types
    // =====

    private:
    typedef std::basic_streambuf<Char, Traits> Base;

    public:
    typedef typename Base::char_type char_type;
    typedef typename Base::int_type int_type;
    typedef typename Base::pos_type pos_type;
    typedef typename Base::off_type off_type;
    typedef typename Base::traits_type traits_type;
    typedef const char_type* pointer;
    typedef std::size_t size_type;

    // Construction
    // ============

    public:
    BasicSequenceInputBuffer(pointer data, size_type size) {
        // These casts are safe (no modification will take place):
        char* begin = const_cast<char_type*>(data);
        char* end = const_cast<char_type*>(data + size);
        this->setg(begin, begin, end);
    }

    // Stream Buffer Interface
    // =======================

    protected:
    virtual std::streamsize showmanyc();
    virtual std::streamsize xsgetn(char_type*, std::streamsize);
    virtual int_type pbackfail(int_type);

    // Utilities
    // =========

    protected:
    int_type eof() { return traits_type::eof(); }
    bool is_eof(int_type ch) { return ch == eof(); }
};


// Get Area
// ========

template <typename Char, typename Traits>
std::streamsize
BasicSequenceInputBuffer<Char, Traits>::showmanyc() {
    return this->egptr() - this->gptr();
}

template <typename Char, typename Traits>
std::streamsize
BasicSequenceInputBuffer<Char, Traits>::xsgetn(char_type* p, std::streamsize n) {
    std::streamsize result = std::min(n, this->egptr() - this->gptr());
    std::copy(this->gptr(), this->gptr() + result, p);
    this->gbump(result);
    return result;
}

template <typename Char, typename Traits>
typename BasicSequenceInputBuffer<Char, Traits>::int_type
BasicSequenceInputBuffer<Char, Traits>::pbackfail(int_type ch) {
    if(is_eof(ch)) {
        if(this->eback() != this->gptr()) {
            this->gbump(-1);
            return traits_type::to_int_type(*this->gptr());
        }
    }
    return eof();
}

typedef BasicSequenceInputBuffer<char> SequenceInputBuffer;


// BasicSequenceInputStream
//=============================================================================

template < typename Char, typename Traits = std::char_traits<Char> >
class BasicSequenceInputStream
:   public std::basic_istream<Char, Traits>
{
    private:
    typedef std::basic_istream<Char, Traits> Base;

    public:
    typedef typename Base::char_type char_type;
    typedef typename Base::int_type int_type;
    typedef typename Base::pos_type pos_type;
    typedef typename Base::off_type off_type;
    typedef typename Base::traits_type traits_type;

    private:
    typedef BasicSequenceInputBuffer<Char, Traits> buffer_type;

    public:
    typedef typename buffer_type::pointer pointer;
    typedef typename buffer_type::size_type size_type;

    // Construction
    // ============

    public:
    explicit BasicSequenceInputStream(pointer data, size_type size)
    :   Base(&m_buf), m_buf(data, size)
    {}

    private:
    buffer_type m_buf;
};

typedef BasicSequenceInputStream<char> SequenceInputStream;


// Test
// ====

#include <iostream>
#include <vector>

int main()
{
    const std::string s = "Hello World";
    const std::vector<char> vector(s.begin(), s.end());
    SequenceInputStream stream(vector.data(), vector.size());

    std::string line;
    std::getline(stream, line);
    std::cout << line << '\n';
}