c++11 标准模板(STL)(std::basic_streambuf)(八)

定义于头文件 <streambuf>
template<

    class CharT,
    class Traits = std::char_traits<CharT>

> class basic_streambuf;

 类 basic_streambuf 控制字符序列的输入与输出。它包含下列内容并提供到它们的访问:

1) 受控制字符序列,又称为缓冲区,它可含有为输入操作缓冲的输入序列(又称为获取区),和/或为输出操作缓冲的输出序列(又称为放置区)。

2) 关联字符序列,又称作(对于输入)或(对于输出)。它可以是通过 OS API 访问的实体(文件、 TCP 接头、串行端口、其他字符设备),或者可以是能转译成字符源或池的对象( std::vector 、数组、字符串字面量)。

I/O 流对象 std::basic_istream 及 std::basic_ostream ,还有所有导出自它们的对象( std::ofstream 、 std::stringstream 等),都完全以 std::basic_streambuf 实现。

受保护成员函数

放置区

将多个字符写到输出序列

std::basic_streambuf<CharT,Traits>::sputn, 
std::basic_streambuf<CharT,Traits>::xsputn

std::streamsize sputn( const char_type* s, std::streamsize count );

(1)

protected:
virtual std::streamsize xsputn( const char_type* s, std::streamsize count );

(2)

1) 调用最终导出类的 xsputn(s, count)

2) 从首元素为 s 所指向的数组写 count 个字符到输出序列。如同以重复调用 sputc() 写入字符。在写入 count 字符后或调用 sputc() 会返回 Traits::eof() 时写入停止。

若放置区变满( pptr() == epptr() ),则此函数可调用 overflow() ,或以其他未指定手段达成调用 overflow() 的效果。

参数

(无)

返回值

成功写入的字符数。

注意

“以未指定手段达成 overflow() 的效果”容许无中间缓冲的大量 I/O :这是一些 iostream 的实现中, std::ofstream::write 简单地传递指针给 POSIX write() 系统调用的缘由。

 调用示例

#include <iostream>
#include <sstream>

int main()
{
    std::ostringstream s1;
    std::streamsize sz = s1.rdbuf()->sputn("This is a test", 14);
    s1 << '\n';
    std::cout << "The call to sputn() returned " << sz << '\n'
              << "The output sequence contains " << s1.str();

    std::istringstream s2;
    sz = s2.rdbuf()->sputn("This is a test", 14);
    std::cout << "The call to sputn() on an input stream returned " << sz << '\n';
}
输出

从放置区写入字符到关联的输出序列

std::basic_streambuf<CharT,Traits>::overflow

virtual int_type overflow( int_type ch = Traits::eof() );

通过保存始于 pbase() 的某个起始字符子序列到输入序列,并更新放置区(若需要),确保放置区有至少一个字符的空间。若 ch 不是 Traits::eof() (即 Traits::eq_int_type(ch, Traits::eof()) != true ),则将它放到放置区或直接保存到输出序列。

函数可以更新 pptrepptrpbase 指针以定义要写入更多数据的位置。失败时,函数确保 pptr() == nullptr 或 pptr() == epptr 。

函数的基类版本不做任何事。允许此函数的导出类版本在耗尽的情况下更新放置区。

参数

ch-要存储于放置区的字符

返回值

成功时返回不等于 Traits::eof() 的未指定值,失败时返回 Traits::eof() 。

此函数的基类版本返回 Traits::eof() 。

注意

sputc() 和 sputn() 在可能上溢的情况( pptr() == nullptr 或 pptr() >= epptr() )下调用此函数。

调用示例

#include <iostream>
#include <array>

// 以 std::array 实现的 std::ostream 缓冲区
template<std::size_t SIZE, class CharT = char>
class ArrayedStreamBuffer : public std::basic_streambuf<CharT>
{
public:

    using Base = std::basic_streambuf<CharT>;
    using char_type = typename Base::char_type;
    using int_type = typename Base::int_type;

    ArrayedStreamBuffer() : buffer_{} // 值初始化 buffer_ 为全零
    {
        Base::setp(buffer_.begin(), buffer_.end()); // 设置 std::basic_streambuf
        // 放置区指针以 'buffer_' 工作
    }

    int_type overflow(int_type ch)
    {
        std::cout << "overflow\n";
        return Base::overflow(ch);
    }

    void print_buffer()
    {
        for (const auto& i : buffer_)
        {
            if (i == 0)
            {
                std::cout << "NULL";
            }
            else
            {
                std::cout << i;
            }
            std::cout << " ";
        }
        std::cout << "\n";
    }

private:
    std::array<char_type, SIZE> buffer_;
};

int main()
{
    ArrayedStreamBuffer<10> streambuf;
    std::ostream stream(&streambuf);

    stream << "hello";
    streambuf.print_buffer();
    if (stream.good())
    {
        std::cout << "stream is good\n";
    }

    stream << "world";
    streambuf.print_buffer();
    if (stream.good())
    {
        std::cout << "stream is good\n";
    }

    stream << "!";
    streambuf.print_buffer();
    if (!stream.good())
    {
        std::cout << "stream is not good\n";
    }
}
 输出

返回指向放置区的起始、当前字符和末尾的指针

std::basic_streambuf<CharT,Traits>::pbase, 
std::basic_streambuf<CharT,Traits>::pptr, 
std::basic_streambuf<CharT,Traits>::epptr

char_type* pbase() const;

(1)

char_type* pptr() const;

(2)

char_type* epptr() const;

(3)

返回定义放置区的指针。

1) 返回指向放置区起始(“基”)的指针。

2) 返回指向放置区中当前字符的指针(放置指针)。

3) 返回指向放置区结尾后一位置的指针。

参数

(无)

返回值

1) 指向放置区起始的指针。

2) 指向放置区中当前字符的指针(放置指针)。

3) 指向放置区结尾后一位置的指针。

令输出序列中的下一位置指针前进

std::basic_streambuf<CharT,Traits>::gbump

void gbump( int count );

 跳过获取区中的 count 个字符。通过令获取指针前进 count 个字符。不为下溢做检查。

参数

count-要跳过的字符数

返回值

(无)

注意

因为此函数接收 int ,故它无法操纵大于 std::numeric_limits<int>::max() 字符的缓冲区( LWG 255 )。

重定位输出序列的起始、下一位置和终止指针

std::basic_streambuf<CharT,Traits>::setp

void setp( char_type* pbeg, char_type* pend );

设置定义放置区的指针值。特别是调用后 pbase() == pbeg 、 pptr() == pbeg 、 epptr() == pend 。

参数

pbeg-指向放置区新起始的指针
pend-指向放置区新结尾的指针

返回值

(无)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值