std::ios_base

ios_base 类是一个多用途类,用作所有 I/O 流类的基类。它维护着几种数据:

  • 状态信息:流状态标志
  • 控制信息:控制输入和输出序列的格式以及语言环境的标志
  • 私有存储:可扩展索引数据结构,允许 longvoid* 成员,它可以实现为两个任意长度的数组或两个元素结构的单个数组或另一个容器
  • 回调函数:从 imbue()std::basic_ios::copyfmt()~ios_base() 调用的任意数量的用户定义函数

成员变量

openmode

流打开的模式类型,包括以下常量值

  • app: 在每次写入之前移到流的末尾(追加模式)
  • binary: 以二进制方式打开
  • in: 以读取的方式打开
  • out: 以写入的方式打开
  • trunc: 打开时丢弃流的内容
  • ate: 打开后立即移到流的末尾

MSVC 中定义如下:

enum _Openmode { // constants for file opening options
_Openmask = 0xff
};

static constexpr _Openmode in = static_cast<_Openmode>(0x01);
static constexpr _Openmode out = static_cast<_Openmode>(0x02);
static constexpr _Openmode ate = static_cast<_Openmode>(0x04);
static constexpr _Openmode app = static_cast<_Openmode>(0x08);
static constexpr _Openmode trunc = static_cast<_Openmode>(0x10);
static constexpr _Openmode binary = static_cast<_Openmode>(0x20);

fmtflags

格式化标志

  • dec: 整数 I/O 使用十进制基数
  • oct: 整数 I/O 使用八进制基数
  • hex: 整数 I/O 使用十六进制基数
  • basefield: dec|oct|hex, 对屏蔽操作很有用
  • left: 左对齐(向右添加填充字符)
  • right: 右对齐(向左添加填充字符)
  • internal: 内部调整(将填充字符添加到内部指定点)
  • adjustfield: left|right|internal, 对屏蔽操作很有用
  • scientific: 使用科学记数法或十六进制记数法(如果与 fixed 结合)生成浮点类型
  • fixed: 使用固定表示法或十六进制表示法(如果与 scientific 结合)生成浮点类型
  • floatfield: scientific|fixed, 对屏蔽操作很有用
  • boolalpha: 以字母数字格式插入和提取布尔类型
  • showbase: 生成指示整数输出的数字基数的前缀
  • showpoint: 为浮点数输出无条件生成小数点字符
  • showpos: 为非负数输出生成 + 字符
  • skipws: 在某些输入操作之前跳过前导空格
  • unitbuf: 每次输出操作后刷新输出
  • uppercase: 在某些输出操作中的等价条件下,用大写字母替换某些小写字母

MSVC 中定义如下:

enum _Fmtflags { // constants for formatting options
_Fmtmask = 0xffff,
_Fmtzero = 0
};

static constexpr _Fmtflags skipws = static_cast<_Fmtflags>(0x0001);
static constexpr _Fmtflags unitbuf = static_cast<_Fmtflags>(0x0002);
static constexpr _Fmtflags uppercase = static_cast<_Fmtflags>(0x0004);
static constexpr _Fmtflags showbase = static_cast<_Fmtflags>(0x0008);
static constexpr _Fmtflags showpoint = static_cast<_Fmtflags>(0x0010);
static constexpr _Fmtflags showpos = static_cast<_Fmtflags>(0x0020);
static constexpr _Fmtflags left = static_cast<_Fmtflags>(0x0040);
static constexpr _Fmtflags right = static_cast<_Fmtflags>(0x0080);
static constexpr _Fmtflags internal = static_cast<_Fmtflags>(0x0100);
static constexpr _Fmtflags dec = static_cast<_Fmtflags>(0x0200);
static constexpr _Fmtflags oct = static_cast<_Fmtflags>(0x0400);
static constexpr _Fmtflags hex = static_cast<_Fmtflags>(0x0800);
static constexpr _Fmtflags scientific = static_cast<_Fmtflags>(0x1000);
static constexpr _Fmtflags fixed = static_cast<_Fmtflags>(0x2000);

static constexpr _Fmtflags hexfloat = static_cast<_Fmtflags>(0x3000); // added with TR1 (not in C++11)

static constexpr _Fmtflags boolalpha = static_cast<_Fmtflags>(0x4000);
static constexpr _Fmtflags _Stdio = static_cast<_Fmtflags>(0x8000);
static constexpr _Fmtflags adjustfield = static_cast<_Fmtflags>(0x01C0); // left | right | internal
static constexpr _Fmtflags basefield = static_cast<_Fmtflags>(0x0E00); // dec | oct | hex
static constexpr _Fmtflags floatfield = static_cast<_Fmtflags>(0x3000); // scientific | fixed

iostate

流的状态

  • goodbit: 没有错误
  • badbit: 不可恢复的流错误
  • failbit: 输入/输出操作失败(格式化或提取错误)
  • eofbit: 关联的输入序列已到达文件结尾

MSVC 中定义如下:

enum _Iostate { // constants for stream states
_Statmask = 0x17
};

static constexpr _Iostate goodbit = static_cast<_Iostate>(0x0);
static constexpr _Iostate eofbit = static_cast<_Iostate>(0x1);
static constexpr _Iostate failbit = static_cast<_Iostate>(0x2);
static constexpr _Iostate badbit = static_cast<_Iostate>(0x4);

seekdir

流指针位置

  • beg: 流开始位置
  • end: 流末尾位置
  • cur: 流当前的位置

MSVC 中定义如下:

enum _Seekdir { // constants for file positioning options
_Seekbeg,
_Seekcur,
_Seekend
};

static constexpr _Seekdir beg = _Seekbeg;
static constexpr _Seekdir cur = _Seekcur;
static constexpr _Seekdir end = _Seekend;

event

事件。指定传递给 register_callback() 在特定事件上注册的函数的事件类型。

  • erase_event
  • imbue_event
  • copyfmt_event

event_callback

事件函数回调

typedef void (*event_callback)(event type, ios_base& ios, int index);

成员函数

flags

fmtflags flags() const;          // 获取当前设置的格式
fmtflags flags(fmtflags flags); // 替换当前的格式

setf

fmtflags setf(fmtflags flags);                // 设置当前格式,fl = fl | flags
fmtflags setf(fmtflags flags, fmtflags mask); // 设置当前格式,清除 mask 标志,设置 flags 标志 fl = (fl & ~mask) | (fl & mask)

unsetf

void unsetf(fmtflags flags);  // 取消设置由标志标识的格式化标志

precision

using streamsize = long long;
streamsize precision() const; // 获取当前设置的精度
streamsize precision(streamsize new_precision); // 设置当前精度,返回前一次的精度

width

streamsize width() const;                // 获取当前设置的宽度
streamsize width(streamsize new_width); // 设置当前宽度,返回前一次设置的宽度

imbue

std::locale imbue(const std::locale& loc); // 设置语言环境,返回前一次设置的语言环境

getloc

std::locale getloc() const; // 获取当前的语言环境

xalloc & iword & pword

static int xalloc();     // 返回一个范围内的唯一整数,可以安全地用作 pword() 和 iword() 的索引
long& iword(int index); // 如有必要,调整私有存储的大小,并访问给定索引 long 元素
void*& pword(int index); // 如有必要,调整私有存储的大小,并访问给定索引 void* 元素

register_callback

注册回调函数,回调函数可能会被 imbue(), std::basic_ios::copyfmt()~ios_base() 调用。

回调以注册的相反顺序调用。如果从回调函数中调用 register_callback() 以添加新回调,则仅在下一个事件时调用新回调。

用户自定义回调函数不允许抛出异常。

typedef void (*event_callback)(event type, ios_base& ios, int index);

void register_callback(event_callback function, int index);

sync_with_stdio

设置标准 C++ 流是否在每次输入/输出操作后与标准 C 流同步。

标准 c++ 流包括:std::cin, std::cout, std::cerr, std::clog, std::wcin, std::wcout, std::wcerr, std::wclog

标准 C 流包括:stdcin, stdcout, stderr

对于一个标准流 str,与 C 流 f 同步,则以下情况是等效的:

  • std::fputc(f, c) & str.rdbuf()->sputc(c)
  • std::fgetc(f) & str.rdbuf()->sbumpc()
  • std::ungetc(c, f) & str.rdbuf()->sputbackc(c)

实际上,这意味着同步的 C++ 流是无缓冲的,并且 C++ 流上的每个 I/O 操作都会立即应用于相应的 C 流的缓冲区。这使得自由混合 C++ 和 C I/O 成为可能。

此外,同步的 C++ 流保证是线程安全的。如果关闭同步,则允许 C++ 标准流独立缓冲其 I/O,这在某些情况下可能会快得多。

failure 类

failure 类定义了输入输出库在调用函数失败时抛出的异常。从 c++ 11 之后,failure 的继承关系如下:

exception <- runtime_error <- system_errro <- ios_base::failure
explicit failure(const std::string& message);
explicit failure(const std::string& message, const std::error_code& ec = std::io_errc::stream);
explicit failure(const char* message, const std::error_code& ec = std::io_errc::stream);
failure(const failure& other);
failure(const failure& other) noexcept;

failure& operator=(const failure& other);
failure& operator=(const failure& other) noexcept;

virtual const char* what() const throw();
virtual const char* what() const noexcept;

std::basic_ios

std::basic_ios 定义在 <ios> 头文件中,其声明如下:

template<class CharT, class Traits = std::char_traits<CharT>>
class basic_ios : public std::ios_base

对于 char 和 wchar_t,有对应的偏特化模板

using ios = basic_ios<char, char_traits<char>>;
using wios = basic_ios<wchar_t, char_traits<wchar_t>>;

成员函数

constructor & destructor

explicit basic_ios(std::basic_streambuf<CharT,Traits>* sb);
~basic_ios() noexcept override

State functions

iostate rdstate() const;        // 返回当前流错误状态
bool good() const; // 如果最近的 I/O 操作成功,则返回 true,rdstate() == goodbit
bool eof() const; // 如果关联的流已到达文件结尾,则返回 true,rdstate() & eofbit
bool fail() const; // 如果关联的流发生错误,则返回 true,rdstate() & (badbit | failbit)
bool bad() const; // 如果关联流上发生不可恢复的错误,则返回 true,rdstate() & badbit
bool operator!() const; // 如果关联流发生错误,则返回 true, 和 fail() 等效
explicit operator bool() const; // 如果流没有错误并且准备好进行 I/O 操作,则返回 true,和 !fail() 等效
void setstate(iostate state); // 设置流状态标志,可能会抛异常

void clear(std::ios_base::iostate state = std::ios_base::goodbit); // 修改流状态标志,可能会抛异常

copyfmt

如果 other*this 是同一个对象,则不会有效果。否则,拷贝 other 对象中的状态到 *this 中。

basic_ios& copyfmt(const basic_ios& other);

fill

fill 管理用于将输出转换填充到指定字段宽度的填充字符

CharT fill() const;     // 获取当前设置的填充字符
CharT fill(CharT ch); // 设置填充字符,并返回上次设置的填充字符

exceptions

exceptions 管理异常掩码标志,异常掩码确定哪些错误状态会触发失败类型的异常。如果流在调用时具有被异常掩码覆盖的错误状态,则会立即触发异常。

std::ios_base::iostate exceptions() const;       // 获取异常掩码
void exceptions(std::ios_base::iostate except); // 设置异常掩码

imbue

imbue 设置语言环境

std::locale imbue(const std::locale& loc);  // 设置语言环境,并返回上次的语言环境

rdbuf

管理相关的流缓冲区。

相关函数可能会抛异常

这里 rd 前缀表示 read,参考 What does STL “rdbuf” method name stand for?

// 返回关联的流缓冲区,如果没有关联的流缓冲区,则返回一个空指针
std::basic_streambuf<CharT, Traits>* rdbuf() const;

// 将关联的流缓冲区设置为 sb,返回之前关联的流缓冲区
std::basic_streambuf<CharT, Traits>* rdbuf(std::basic_streambuf<CharT, Traits>* sb);

tie

管理绑定的流。绑定流是与流缓冲区 (rdbuf()) 控制的序列同步的输出流,也就是说,在对 *this 进行任何输入/输出操作之前,在绑定流上调用 flush()

相关函数可能抛异常

// 返回当前绑定的流。如果没有绑定流,则返回空指针
std::basic_ostream<CharT, Traits>* tie() const;

// 将当前绑定的流设置为 str。返回之前绑定的流。如果没有绑定流,则返回空指针
std::basic_ostream<CharT, Traits>* tie(std::basic_ostream<CharT, Traits>* str);

narrow

将当前特定于语言环境的字符 c 转换为其标准等效字符。如果需要,结果会从 char_type 转换为 char。如果无法执行转换,则该函数返回 dfault。

等效于调用 std::use_facet<std::ctype<char_type>>(getloc()).narrow(c, dfault);

char narrow(char_type c, char dfault) const;

widen

将字符 c 转换为当前语言环境中的等效字符。如果需要,结果会从 char 转换为流中使用的字符类型。

等效于调用 std::use_facet<std::ctype<char_type>>(getloc()).widen(c)

char_type widen(char c) const;

init

将关联的流缓冲区设置为 sb 并初始化内部状态。此成员函数是受保护的:一旦相关的流缓冲区已知,它就由派生流类 std::basic_istreamstd::basic_ostream 的构造函数调用。

protected:
void init(std::basic_streambuf<CharT,Traits>* sb);

初始化后状态如下:

Element Value
rdbuf() sb
tie() null pointer
rdstate() goodbit if sb is not a null pointer, otherwise badbit
exceptions() goodbit
flags() `skipws dec`
width() ​0​
precision() 6
fill() widen(' ')
getloc() a copy of the value returned by std::locale()

move

将当前状态(rdbuf 除外)替换为其他状态。other 在调用后处于有效但未指定的状态。调用此函数后,rdbuf() 返回空指针,other.rdbuf() 返回与调用前相同的值,other.tie() 返回空指针。

protected:
void move(basic_ios& other);
void move(basic_ios&& other);

swap

交换 *this 和 other 的状态(rdbuf 除外)。rdbuf()other.rdbuf() 返回与调用前相同。

protected:
void swap(basic_ios& other) noexcept;

set_rdbuf

将关联的流缓冲区设置为 sb 而不清除错误状态。

protected:
void set_rdbuf(std::basic_streambuf<CharT,Traits>* sb);

std::basic_streambuf

template<
class CharT,
class Traits = std::char_traits<CharT>
> class basic_streambuf;

std::basic_streambuf 定义在 <streambuf> 头文件中

类 basic_streambuf 控制字符序列的输入和输出。其包括:

  • 受控字符序列,也称为缓冲区。缓冲区中包含用于缓冲输入操作的输入序列(也称为 get area)和/或用于缓冲输出操作的输出序列(也称为 put area
  • 关联的字符序列,也称为 source(用于输入)或 sink(用于输出)。这可能是通过 OS API 访问的实体(文件、TCP 套接字、串行端口、其他字符设备),也可能是可以解释为字符 source 或 sink 的对象(std::vector、数组、字符串字面量)

I/O 流对象(std::basic_istream, std::basic_ostream 及其继承的对象)都是根据 std::basic_streambuf 来实现的。

受控字符序列是一个 CharT 数组,它始终表示一个子序列,或关联字符序列的“窗口”。它的状态由三个指针描述:

  • 开始指针(下文用 begin 代替),总是指向缓冲区的最低元素
  • 下一个指针(下文用 next 代替),指向下一个读取或写入候选的元素
  • 结束指针(下文用 end 代替),指向缓冲区末尾的下一个位置

basic_streambuf 对象可以支持输入、输出或同时输入输出。

  • 在作为输入时,3 个指针构成 get area
  • 在最为输出时,3 个指针构成 put area
  • 在输入输出时,会追踪 6 个指针,它们可能都指向同一个字符数组或指向两个单独的数组

在 put area 中,当 next 指针小于 end 指针时认为写位置(write position)可用。next 指针可以解引用和赋值

在 get area 中,当 next 指针小于 end 指针时认为读位置(read position)可用。next 指针可以解引用和赋值

在 get area 中,当 next 指针大于 begin 指针时认为回退位置(putback position)可用。next 指针可以递减、解引用和赋值。能够将字符放回去

受控序列中的字符表示和编码可能与关联序列中的字符表示不同,这种情况下,通常使用 std::codecvt locale facet 来执行转换。

std::basic_streambuf 基类的典型实现仅包含六个 CharT* 指针和 std::locale 的副本作为数据成员。此外,实现可以保留 locale facet 的缓存副本,只要 imbue() 被调用,这些副本就会失效。std::basic_filebufstd::basic_stringbuf 之类的具体缓冲区是从 std::basic_streambuf 派生的。

两种常见的偏特化:

using stringbuf = basic_stringbuf<char, char_traits<char>, allocator<char>>;
using wstringbuf = basic_stringbuf<wchar_t, char_traits<wchar_t>, allocator<wchar_t>>;

Locales

imbue

虚函数,由派生类实现。设置关联的 locale 为 loc

protected:
virtual void imbue(const std::locale& loc);

pubimbue

设置关联的 locale 为 loc,调用派生类的 imbue 实现。返回上次设置的 locale

std::locale pubimbue(const std::locale& loc);

getloc

获取关联的 locale。关联的 locale 是通过最后一次调用 pubimbue 设置的。如果未调用过 pubimbue,则返回构造时的全局 locale

std::locale getloc() const;

Positioning

setbuf & seekoff & seekpos & sync

setbuf, seekoff, seekpossync 为虚函数,需要派生类实现自己的功能。

protected:
// 设置缓冲区为传入的数组。返回 this
virtual basic_streambuf<CharT, Traits>* setbuf(char_type* s, std::streamsize n);

// 根据模式和相对偏移改变位置。返回位置指示器所在的绝对位置
virtual pos_type seekoff(
off_type off,
std::ios_base::seekdir dir,
std::ios_base::openmode which = ios_base::in | ios_base::out);

// 根据模式和位置改变位置。返回位置指示器所在的绝对位置
virtual pos_type seekpos(
pos_type pos,
std::ios_base::openmode which = std::ios_base::in | std::ios_base::out);

// 与关联的字符序列进行同步。成功返回 0,否则返回 -1
virtual int sync();

pubsetbuf & pubsetseekoff & pubseekpos & pubsync

pubsetbuf, pubseekoff, pubseekpospubsync 通过调用派生类实现的上面介绍的对象接口来实现。其功能和对应虚函数相同。

public:
// 设置缓冲区为传入的数组。返回 this
basic_streambuf<CharT, Traits>* pubsetbuf(char_type* s, std::streamsize n);

// 根据模式和相对偏移改变位置。返回位置指示器所在的绝对位置
pos_type pubseekoff(
off_type off,
std::ios_base::seekdir dir,
std::ios_base::openmode which = ios_base::in | ios_base::out);

// 根据模式和位置改变位置。返回位置指示器所在的绝对位置
pos_type pubseekpos(
pos_type pos,
std::ios_base::openmode which = std::ios_base::in | std::ios_base::out);

// 与关联的字符序列进行同步。成功返回 0,否则返回 -1
int pubsync();

Get area

这部分函数是针对输入流缓冲区的操作

showmanyc [virtual]

虚函数,由派生类实现。估计关联字符序列中可用于输入的字符数。

The name of this function stands for “stream: how many characters?”, so it is pronounced “S how many C”, rather than “show many C”.

protected:
virtual std::streamsize showmanyc();

underflow [virtual]

虚函数,需要由派生类实现。通过更新指向输入区的指针(如果需要)并从输入序列中读取更多数据(如果适用),确保输入区中至少有一个字符可用。返回可用字符的数量

protected:
virtual int_type underflow();

uflow [virtual]

虚函数,需要由派生类实现。通过更新指向输入区的指针(如果需要)确保输入区中至少有一个字符可用。成功时返回该字符的值并将 get 指针的值前移一个字符。

protected:
virtual int_type uflow();

xsgetn

虚函数,需要由派生类实现。从输入序列中读取指定数量的字符到 s 中。返回实际读取到的字符数量

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

eback & gptr & egptr

获取输入区相关指针

While the names “gptr” and “egptr” refer to the get area, the name “eback” refers to the end of the putback area: stepping backwards from gptr, characters can be put back until eback.

char_type* eback() const;  // 指向输入区 begin 的指针
char_type* gptr() const; // 指向输入区 current 的指针
char_type* egptr() const; // 指向输入区 end 的下一个指针

gbump

从输入区中跳过 count 个字符

protected:
void gbump(int count);

setg

设置输入缓冲区的指针

protected:
void setg(char_type* gbeg, char_type* gcurr, char_type* gend);

std::basic_istream

template<
class CharT,
class Traits = std::char_traits<CharT>
> class basic_istream : virtual public std::basic_ios<CharT, Traits>

std::basic_istream 是类模板,提供字符流的高级输入。支持的操作包括格式化输入(例如整数值或空格分隔的字符和字符串)和未格式化输入(例如原始字符和字符数组)

该类模板中函数是根据底层 basic_streambuf 类提供的接口实现的,通过 basic_ios 基类访问。

在大多数实现中,basic_istream 的唯一非继承数据成员是 basic_istream::gcount() 返回的值。

该模板定义了两种常见的偏特化:

using istream = basic_istream<char, char_traits<char>>;
using wistream = basic_istream<wchar_t, char_traits<wchar_t>>;

constructor

explicit basic_istream(std::basic_streambuf<CharT, Traits>* sb);
protected:
basic_istream(const basic_istream& rhs) = delete;
basic_istream(basic_istream&& rhs);

operator=

protected:
basic_istream& operator=(const basic_istream& rhs) = delete;
basic_istream& operator=(basic_istream&& rhs);

operator>>

控制输入流的格式,提取对应类型的值

basic_istream& operator>>(short& value);
basic_istream& operator>>(unsigned short& value);

basic_istream& operator>>(int& value);
basic_istream& operator>>(unsigned int& value);

basic_istream& operator>>(long& value);
basic_istream& operator>>(unsigned long& value);

basic_istream& operator>>(long long& value);
basic_istream& operator>>(unsigned long long& value);

basic_istream& operator>>(float& value );
basic_istream& operator>>(double& value);
basic_istream& operator>>(long double& value);

basic_istream& operator>>(bool& value);

basic_istream& operator>>(void*& value);

// func is an I/O manipulator
basic_istream& operator>>(std::ios_base& (*func)(std::ios_base&));
basic_istream& operator>>(std::basic_ios<CharT,Traits>& (*func)(std::basic_ios<CharT,Traits>&));
basic_istream& operator>>(basic_istream& (*func)(basic_istream&));

basic_istream& operator>>(std::basic_streambuf<CharT,Traits>* sb);

get

从流中提取一个或多个字符。

int_type get();  // 读取一个字符并在可用时返回
basic_istream& get(char_type& ch); // 读取一个字符并将其存储到 ch

// 最多读取 count-1 个字符并将它们存储到 s 指向的字符串中,直到找到 '\n'
basic_istream& get(char_type* s, std::streamsize count);

// 读取字符并将它们存储到第一个元素由 s 指向的字符数组的连续位置中,最多存储 count-1 个字符, 直到找到 delim
basic_istream& get(char_type* s, std::streamsize count, char_type delim);

// 读取可用字符并将它们插入给定的 basic_streambuf 对象,直到找到 '\n'
basic_istream& get(basic_streambuf& strbuf);
basic_istream& get(basic_streambuf& strbuf, char_type delim);

peek

在构造和测试 sentry object后,从输入流中读取下一个字符而不提取。可能会抛异常

int_type peek();

unget

使最近提取的字符再次可用。可能会抛异常

basic_istream& unget();

putback

将字符 ch 放回输入流,以便下一个提取的字符是 ch。可能会抛异常

basic_istream& putback(char_type ch);

getline

从流中提取字符直到行尾或指定的分隔符 delim。可能会抛异常

basic_istream& getline(char_type* s, std::streamsize count);  // 默认 delim 为 \n
basic_istream& getline(char_type* s, std::streamsize count, char_type delim);

ignore

从输入流中提取和丢弃字符,直到并包括 delim。可能会抛异常

basic_istream& ignore(std::streamsize count = 1, int_type delim = Traits::eof());

read

从流中提取字符。可能会抛异常

basic_istream& read(char_type* s, std::streamsize count);

readsome

从输入流中提取最多 count 个立即可用的字符。提取的字符存储到 s 指向的字符数组中。可能会抛异常

std::streamsize readsome(char_type* s, std::streamsize count);

gcount

返回由最后一个无格式输入操作提取的字符数,如果该数字不可表示,则返回 std::streamsize 的最大可表示值。

std::streamsize gcount() const;

tellg

返回当前关联的 streambuf 对象的输入位置指示符。可能会抛异常

这里 g 可以看做是 get position

pos_type tellg();

seekg

设置当前关联的 streambuf 对象的输入位置指示器。可能会抛异常

这里 g 可以看做是 get position

basic_istream& seekg(pos_type pos);  // 绝对位置
basic_istream& seekg(off_type off, std::ios_base::seekdir dir); // 相对位置,beg, end, cur

sync

将输入缓冲区与关联的数据源同步。

int sync();

swap

protected:
void swap(basic_istream& rhs);

std::basic_ostream

template<
class CharT,
class Traits = std::char_traits<CharT>
> class basic_ostream : virtual public std::basic_ios<CharT, Traits>

类模板 basic_ostream 为字符流的高级输出操作提供支持。支持的操作包括格式化输出(例如整数值)和未格式化输出(例如原始字符和字符数组)

该类模板中的函数是根据 basic_streambuf 类提供的接口实现的,通过 basic_ios 基类访问。在典型的实现中,basic_ostream 没有非继承的数据成员。

有以下两个常用类型的偏特化:

using ostream = basic_ostream<char, char_traits<char>>;
using wostream = basic_ostream<wchar_t, char_traits<wchar_t>>;

constructor

explicit basic_ostream(std::basic_streambuf<CharT, Traits>* sb);
protected:
basic_ostream(const basic_ostream& rhs) = delete;
basic_ostream(basic_ostream&& rhs);

operator=

protected:
basic_ostream& operator=(const basic_ostream& rhs) = delete;
basic_ostream& operator=(basic_ostream&& rhs);

operator<<

插入数据到流中

basic_ostream& operator<<(short value);
basic_ostream& operator<<(unsigned short value);

basic_ostream& operator<<(int value);
basic_ostream& operator<<(unsigned int value);

basic_ostream& operator<<(long value);
basic_ostream& operator<<(unsigned long value);

basic_ostream& operator<<(long long value);
basic_ostream& operator<<(unsigned long long value);

basic_ostream& operator<<(float value);
basic_ostream& operator<<(double value);
basic_ostream& operator<<(long double value);

basic_ostream& operator<<(bool value);
basic_ostream& operator<<(const void* value);
basic_ostream& operator<<(const volatile void* value);
basic_ostream& operator<<(std::nullptr_t);

basic_ostream& operator<<(std::basic_streambuf<CharT, Traits>* sb);

// func is an I/O manipulator
basic_ostream& operator<<(std::ios_base& (*func)(std::ios_base&));
basic_ostream& operator<<(
std::basic_ios<CharT,Traits>& (*func)(std::basic_ios<CharT,Traits>&));
basic_ostream& operator<<(
std::basic_ostream<CharT,Traits>& (*func)(std::basic_ostream<CharT,Traits>&) );

put

插入一个字符到流中

basic_ostream& put(char_type ch);

write

插入字符串到流中,最多插入 count 个字符,可能会抛异常。

basic_ostream& write(const char_type* s, std::streamsize count);

tellp

返回当前关联的 streambuf 对象的输出位置指示符。不会抛异常,失败返回 -1

这里 p 可以看做是 put position

pos_type tellp();

seekp

设置当前关联的 streambuf 对象的输出位置指示器。可能会抛异常。

basic_ostream& seekp(pos_type pos);  // 绝对位置
basic_ostream& seekp(off_type off, std::ios_base::seekdir dir); // 相对于 beg, cur, end 的相对位置

flush

将未提交的更改写入基础输出序列。如果 rdbuf() 是空指针,则不执行任何操作。可能会抛异常。

basic_ostream& flush();

swap

protected:
void swap(basic_ostream& rhs);

std::basic_iostream

template<
class CharT,
class Traits = std::char_traits<CharT>
> class basic_iostream
: public basic_istream<CharT, Traits>
, public basic_ostream<CharT, Traits>

两个常见类型的偏特化:

using iostream = basic_iostream<char, char_traits<char>>;
using wiostream = basic_iostream<wchar_t, char_traits<wchar_t>>;

constructor

explicit basic_iostream(std::basic_streambuf<CharT,Traits>* sb);
basic_iostream(const basic_iostream& other) = delete;
protected:
basic_iostream(basic_iostream&& other);

operator=

basic_iostream& operator=(const basic_iostream& other) = delete;
protected:
basic_iostream& operator=(basic_iostream&& other);

swap

protected:
void swap(basic_iostream& other);

std::basic_stringbuf

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_istringstream

template<
class CharT,
class Traits = std::char_traits<CharT>,
class Allocator = std::allocator<CharT>
> class basic_istringstream: public basic_istream<CharT, Traits>

std::basic_istringstream 继承与 std::basic_istream

类模板 std::basic_istringstream 在基于字符串的流上实现输入操作。它有效地存储 std::basic_string 的实例并对其执行输入操作。

底层实现是调用的 std::basic_stringbuf 的接口。

对于常用类型的偏特化:

using istringstream = basic_istringstream<char, char_traits<char>, allocator<char>>;
using wistringstream = basic_istringstream<wchar_t, char_traits<wchar_t>, allocator<wchar_t>>;

constructor

// 默认构造函数,使用默认打开方式构造
basic_istringstream() : basic_istringstream(std::ios_base::in) { }

// 使用 mode | std::ios_base::in 构造
explicit basic_istringstream(std::ios_base::openmode mode);

explicit basic_istringstream( const std::basic_string<CharT,Traits,Allocator>& str,
std::ios_base::openmode mode = std::ios_base::in );