C++ 设置std::istringstream的内部缓冲区

C++ 设置std::istringstream的内部缓冲区,c++,macos,buffer,istream,C++,Macos,Buffer,Istream,在升级到OSX10.9.4之前,我有一段在OSX中使用的代码 代码如下: #include <iostream> #include <sstream> int main() { // Buffer to be read const char* buffer = "0 3"; std::cout << "buffer: '" << buffer << "'\n"; size_t len = 3;

在升级到OSX10.9.4之前,我有一段在OSX中使用的代码 代码如下:

#include <iostream>
#include <sstream>

int main() {
    // Buffer to be read
    const char* buffer = "0 3";
    std::cout << "buffer: '" << buffer << "'\n";
    size_t len = 3;

    std::istringstream iss;
    iss.clear();
    iss.rdbuf()->pubsetbuf((char*)buffer, len);

    // Did iss got a hold of buffer?
    std::cout << "str: '" << iss.str() << "'\n";
}
我在机器中获得的电流输出是

buffer: '0 3'
str: ''

这意味着未设置
istringstream中的内部缓冲区。

您可以编写自己的:

#include <algorithm>
#include <ostream>

// BasicInputSequenceBuffer
// ============================================================================

template < typename Char, typename Traits = std::char_traits<Char> >
class BasicInputSequenceBuffer
:   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:
    BasicInputSequenceBuffer(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
BasicInputSequenceBuffer<Char, Traits>::showmanyc() {
    return this->egptr() - this->gptr();
}

template <typename Char, typename Traits>
std::streamsize
BasicInputSequenceBuffer<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 BasicInputSequenceBuffer<Char, Traits>::int_type
BasicInputSequenceBuffer<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 BasicInputSequenceBuffer<char> InputSequenceBuffer;


// BasicInputSequence
//=============================================================================

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

    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 BasicInputSequenceBuffer<Char, Traits> buffer_type;

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

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

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

    private:
    buffer_type m_buf;
};

typedef BasicInputSequence<char> InputSequence;

#include <iostream>

int main() {
    const char* buffer = "0 3";
    InputSequence stream(buffer, 3);
    std::string a;
    std::string b;
    stream >> a >> b;
    std::cout << "str: '" << a << ' ' << b << "'\n";
    return 0;
}
#包括
#包括
//BasicInputSequenceBuffer
// ============================================================================
模板
类BasicInputSequenceBuffer
: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;
//建筑
// ============
公众:
BasicInputSequenceBuffer(指针数据,大小\类型大小){
//这些类型转换是安全的(不会进行任何修改):
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
BasicInputSequenceBuffer::showmanyc(){
返回this->egptr()-this->gptr();
}
模板
std::streamsize
BasicInputSequenceBuffer::xsgetn(字符类型*p,标准::流大小n){
std::streamsize result=std::min(n,this->egptr()-this->gptr());
std::copy(this->gptr(),this->gptr()+结果,p);
此->gbump(结果);
返回结果;
}
模板
typename BasicInputSequenceBuffer::int\u类型
BasicInputSequenceBuffer::pbackfail(int_类型ch){
if(is_eof(ch)){
如果(this->eback()!=this->gptr()){
这->gbump(-1);
返回字符类型::到字符类型(*this->gptr());
}
}
返回eof();
}
typedef BasicInputSequenceBuffer InputSequenceBuffer;
//基本输入序列
//=============================================================================
模板
类基本输入序列
:公共标准::基本信息流
{
//类型
// =====
私人:
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 BasicInputSequenceBuffer_类型;
公众:
typedef typename buffer_type::pointer指针;
typedef typename buffer_type::size_type size_type;
//建筑
// ============
公众:
显式BasicInputSequence(指针数据,大小\类型大小)
:基准(&m_-buf),m_-buf(数据,大小)
{}
私人:
缓冲区类型m_buf;
};
typedef BasicInputSequence输入序列;
#包括
int main(){
常量字符*buffer=“0 3”;
输入序列流(缓冲器,3);
std::字符串a;
std::字符串b;
流>>a>>b;

std::cout您可以编写自己的:

#include <algorithm>
#include <ostream>

// BasicInputSequenceBuffer
// ============================================================================

template < typename Char, typename Traits = std::char_traits<Char> >
class BasicInputSequenceBuffer
:   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:
    BasicInputSequenceBuffer(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
BasicInputSequenceBuffer<Char, Traits>::showmanyc() {
    return this->egptr() - this->gptr();
}

template <typename Char, typename Traits>
std::streamsize
BasicInputSequenceBuffer<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 BasicInputSequenceBuffer<Char, Traits>::int_type
BasicInputSequenceBuffer<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 BasicInputSequenceBuffer<char> InputSequenceBuffer;


// BasicInputSequence
//=============================================================================

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

    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 BasicInputSequenceBuffer<Char, Traits> buffer_type;

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

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

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

    private:
    buffer_type m_buf;
};

typedef BasicInputSequence<char> InputSequence;

#include <iostream>

int main() {
    const char* buffer = "0 3";
    InputSequence stream(buffer, 3);
    std::string a;
    std::string b;
    stream >> a >> b;
    std::cout << "str: '" << a << ' ' << b << "'\n";
    return 0;
}
#包括
#包括
//BasicInputSequenceBuffer
// ============================================================================
模板
类BasicInputSequenceBuffer
: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;
//建筑
// ============
公众:
BasicInputSequenceBuffer(指针数据,大小\类型大小){
//这些类型转换是安全的(不会进行任何修改):
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
BasicInputSequenceBuffer::showmanyc(){
返回this->egptr()-this->gptr();
}
模板
std::streamsize
BasicInputSequenceBuffer::xsgetn(字符类型*p,标准::流大小n){
std::streamsize result=std::min(n,this->egptr()-this->gptr());
std::copy(this->gptr(),this->gptr()+结果,p);
此->gbump(结果);
返回结果;
}
模板
typename BasicInputSequenceBuffer::int\u类型
BasicInputSequenceBuffer::pbackfail(int_类型ch){
if(is_eof(ch)){
如果(this->eback()!=this->gptr()){
这->gbump(-1);
返回字符类型::到字符类型(*this->gptr());
}
}
返回eof();
}
typedef BasicInputSequenceBuffer InputSequenceBuffer;
//基本输入序列
//=============================================================================
模板
类基本输入序列