定义于头文件 <sstream>
template< class CharT, |
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 起) |
亦提供二个对常用字符类型的特化:
类型 | 定义 |
stringbuf | basic_stringbuf<char> |
wstringbuf | basic_stringbuf<wchar_t> |
受保护成员函数
回放字符到输出序列中
std::basic_stringbuf<CharT,Traits,Allocator>::pbackfail
protected: |
此受保护虚函数为公开函数 basic_streambuf::sungetc 和 basic_streambuf::sputbackc 所调用(转而为 basic_istream::unget 和 basic_istream::putback 所调用)。
1) 调用方要求获取区后备一个字符(以无参数或以 Traits::eof() 为参数调用 pbackfail()
)
a) 首先,检查是否有回放位置,而若确实无回放位置则失败( stringbuf 无重读用的外部字符序列)
b) 若调用方错误而回放位置实际上可用,则简单地自减 basic_streambuf::gptr() ,例如以调用 gbump(-1) 。
2) 调用方试图回放的字符异于之前取得者(以要需要放回的字符调用 pbackfail()
),该情况下
a) 首先,检查是否有回放位置,若无则失败。
b) 然后检查会放位置中有什么字符。若其处保有的字符已等于 c
,以 Traits::eq(to_char_type(c), gptr()[-1]) 确定,则简单地自减 basic_streambuf::gptr() 。
c) 否则,若缓冲区仅为读取打开,则失败。
d) 否则,若缓冲区为写入打开( mode && std::ios_base::out 非零),则自减 basic_streambuf::gptr() 并写入 c
到调整后的 gptr() 所指向的位置。
参数
c | - | 要返回的字符,或若要求指示获取区的后备则为 Traits::eof() |
返回值
成功时为 c ,除非 c
为 Traits::eof() ,该情况下返回 Traits::not_eof(c) 。
失败时为 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 pbackfail(int_type c) override
{
std::cout << "Before pbackfail(): get area size is "
<< egptr() - eback() << ' '
<< " put area size is "
<< epptr() - pbase() << std::endl;
int_type ch = std::stringbuf::pbackfail(c);
std::cout << "After pbackfail(): get area size is "
<< egptr() - eback() << ' '
<< " put area size is "
<< epptr() - pbase() << std::endl;
if (ch == EOF)
{
std::cout << "pbackfail() returns EOF\n";
}
else
{
std::cout << "pbackfail() returns '"
<< char(ch) << "'" << std::endl;
}
return ch;
}
};
int main()
{
mybuf sbuf("12345"); // 读写流
sbuf.sungetc();
std::cout << std::endl;
sbuf.sputbackc('5');
return 0;
}
输出
后附字符到输出序列
std::basic_stringbuf<CharT,Traits,Allocator>::overflow
protected: |
后附字符 c
到输出字符序列。
若 c
为文件尾指示器( traits::eq_int_type(c,traits::eof()) == true ),则不后附字符。函数不做任何操作并返回异于 traits::eof() 的未指定值。
否则,若输出序列拥有可用写位置,或若此函数成功令一个写位置可用,则调用 sputc(c) 并返回 c
。
若 stringbuf 为输出打开( mode & ios_base::out) != 0 ),则此函数能令写位置可用:此情况下,它重分配(或在最初分配)足够大的缓冲区,以保有整个当前缓冲区加上至少一个字符。若 stringbuf 亦为输入打开( (mode & ios_base::in) != 0 ),则 overflow
亦会通过移动 egptr() 到指向恰好越过新放置区的位置,来增加获取区的大小。
参数
c | - | 要存储于放置区的字符 |
返回值
若失败则为指示失败的 Traits::eof() 。若成功后附字符 c
则为 c
。或若以 Traits::eof() 为参数调用,则为某异于 Traits::eof() 的值。
注意
此函数异于典型的 overflow()
,后者移动缓冲区的内容到关联字符序列,因为 std::basic_stringbuf 的缓冲区和关联序列是同一序列。
调用示例
#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 = EOF) override
{
std::cout << "stringbuf::overflow('"
<< char(c) << "') called" << std::endl
<< "Before: size of get area: "
<< egptr() - eback() << std::endl
<< " size of put area: "
<< epptr() - pbase() << std::endl;
int_type ret = std::stringbuf::overflow(c);
std::cout << "After : size of get area: "
<< egptr() - eback() << std::endl
<< " size of put area: "
<< epptr() - pbase() << std::endl;
return ret;
}
};
int main()
{
std::cout << "read-write stream:" << std::endl;
mybuf sbuf(" "); // 只读流
std::iostream stream(&sbuf);
stream << 1234;
std::cout << sbuf.str() << std::endl;
std::cout << std::endl << "read-only stream:" << std::endl;
mybuf ro_buf(" ", std::ios_base::in); // 只读流
std::iostream ro_stream(&ro_buf);
ro_stream << 1234;
std::cout << std::endl << "write-only stream:" << std::endl;
mybuf wr_buf(" ", std::ios_base::out); // 只写流
std::iostream wr_stream(&wr_buf);
wr_stream << 1234;
return 0;
}
输出