定义于头文件 <streambuf>
template< class CharT, |
类 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: | (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 ),则将它放到放置区或直接保存到输出序列。
函数可以更新 pptr
、 epptr
和 pbase
指针以定义要写入更多数据的位置。失败时,函数确保 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 | - | 指向放置区新结尾的指针 |
返回值
(无)