C++ 读取向量<;char>;如溪流
我有一个常量向量,但需要一个函数来读取它。问题是,函数需要一个istream 将向量中的数据传递到此函数的最有效方法是什么 我尝试了这种方法来防止复制流,但它不起作用,因为我的向量是const,而pubsetbuf需要一个非const 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
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';
}