c++11 标准模板(STL)(std::basic_stringbuf)(四)

定义于头文件 <sstream>
template<

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

> class basic_stringbuf : public std::basic_streambuf<CharT, Traits>

std::basic_stringbuf 是关联字符序列为内存常驻的任意字符序列的 std::basic_streambuf 。能从 std::basic_string 的实例初始化它,或将它做成该类的实例。

std::basic_stringbuf 的典型实现保有一个 std::basic_string 类型对象,或等价的可伸缩序列容器作为数据成员,并将它同时用作受控制字符序列(为 std::basic_streambuf 的六个指针所指向的数组)和关联字符序列(所有输入操作的字符源和输出操作的目标)。

另外,典型的实现保有一个 std::ios_base::openmode 类型的数据成员,以指示流的状态(只读、只写、读写、尾端写等)。

若 overflow() 使用过分配策略,则可存储另外的高水位指针,以跟踪最后初始化的字符。(C++11 起)

亦提供二个对常用字符类型的特化:

类型定义
stringbufbasic_stringbuf<char>
wstringbufbasic_stringbuf<wchar_t>

受保护成员函数

返回输入序列中可用的下一字符

std::basic_stringbuf<CharT,Traits,Allocator>::underflow

protected:
virtual int_type underflow()

从缓冲的获取区读取下个字符。

具体而言:

1) 若输入序列拥有可用的读位置( egptr() > gptr() ),则返回 Traits::to_int_type(*gptr()) 。

2) 否则,若 pptr() > egptr() (从上次更改 egptr() 的 overflow() 起插入了一些字符到流中),则通过更改 egptr() 为等于 pptr() ,扩展获取区结尾以包含最近插入的字符,再返回 Traits::to_int_type(*gptr()) 。

3) 否则,返回 Traits::eof() 。

缓冲区中任何已被初始化的字符,无关乎它源自构造函数中传递的字符串还是为 overflow() 所后附,都被认为是输入序列的一部分。

参数

(无)

返回值

成功情况下为 Traits::to_int_type(*gptr()) (获取区中要读取的下个字符),失败情况下为 Traits::eof() 。

 调用示例

#include <sstream>
#include <string>
#include <iostream>

//  typedef basic_stringbuf<char> 	stringbuf;

struct mybuf : std::stringbuf
{
    mybuf(const std::string& new_str,
          std::ios_base::openmode which =
              std::ios_base::in | std::ios_base::out)
        : std::stringbuf(new_str, which) {}

    int_type overflow(int_type c)
    {
        std::cout << "Before overflow(): get area size is "
                  << egptr() - eback() << ' '
                  << " the put area size is "
                  << epptr() - pbase() << std::endl;

        int_type rc = std::stringbuf::overflow(c);

        std::cout << "After overflow(): get area size is "
                  << egptr() - eback() << ' '
                  << " put area size is "
                  << epptr() - pbase() << std::endl;

        return rc;
    }

    int_type underflow()
    {
        std::cout << "Before underflow(): get area size is "
                  << egptr() - eback() << ' '
                  << " put area size is "
                  << epptr() - pbase() << std::endl;

        int_type ch = std::stringbuf::underflow();

        std::cout << "After underflow(): get area size is "
                  << egptr() - eback() << ' '
                  << " put area size is "
                  << epptr() - pbase() << std::endl;

        if (ch == EOF)
        {
            std::cout << "underflow() returns EOF\n";
        }
        else
        {
            std::cout << "underflow() returns '"
                      << char(ch) << "'" << std::endl;
        }

        return ch;
    }
};

int main()
{
    mybuf sbuf("123"); // 读写流
    std::iostream stream(&sbuf);
    int n;
    stream >> n; // 调用 sgetc() 四次
    // 三次调用返回字符 '1' 、 '2' 、 '3'
    // 第四次调用, gptr() == egptr() 并调用 underflow()
    // underflow 返回 EOF
    std::cout << n << std::endl;
    stream.clear(); // 清除 eofbit

    stream << "123456"; // 调用 sputc() 6 次
    // 前三次调用存储 "123" 于既存缓冲区
    // 第 4 次调用发现 pptr() == epptr() 并调用 overflow()
    // overflow() 令缓冲区生长并设置 egptr() 为 4
    // 第 5 和第 6 次调用存储 '5' 和 '6' ,令 pptr() 前进
    stream >> n; // 调用 sgetc() 4 次
    // 第 1 次调用返回 overflow() 使之可用的 '4'
    // 第 2 次调用时, egptr() == egptr() 并调用 underflow()
    // underflow 令 egptr() 前进到等于 pptr() (which is 6)
    // 第 3 次 sgetc() 返回 '6'
    // 第 4 次 sgetc() 发现 gptr() == egptr() ,调用 underflow()
    // underflow() 返回 EOF
    std::cout << n << std::endl;

    return 0;
}
输出

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值