class ios_base;
流的基类:管理格式化标志和输入/输出异常
- 标准输入输出库中流类整个层次结构的基类,描述了所有流对象共有的流最基本部分(与字符类型无关)
- 它没有公共构造函数,因此无法声明此类的对象
该类
ios_base
是一个多用途类,可作为所有I / O流类的基类。它维护几种数据:1) 状态信息:流状态标志2) 控制信息:控制输入和输出序列以及输入区域的格式化的标志3) 私有存储:索引可扩展的数据结构,允许两者 long 和 void * 成员,可以实现为两个任意长度的数组或两个元素的结构的单个数组或另一个容器。4) 回调:从imbue(),copyfmt()和〜ios_base()调用的任意数量的用户定义函数更具体的说,ios_base 类维护流的以下信息:
典型的实现方式包含与以下所示的fmtflags,iostate,openmode和seekdir的所有值相对应的成员常量,用于维护当前精度,宽度和格式标志的成员变量,异常掩码,缓冲区错误状态,可调整大小的容器(用于保存回调),当前使用的语言环境,私有存储以及xalloc()的静态整数变量。
field 成员函数 描述 Formatting format 标识 flags
setf
unsetf一组内部标志,这些标志影响解释或生成某些输入/输出操作的方式.
具体见成员类型 fmtflags.field width width 下一个要插入的格式化元素的宽度。 显示精度 precision 下一个插入的浮点值的十进制精度。 地区 getloc
imbueThe locale object 用于受本地化属性影响的格式化输入/输出操作的区域设置对象。 Other 回调堆栈 register_callback 指向某些事件发生时调用的函数的指针的堆栈。 可扩展数组 iword
pword
xalloc用于存储long和void*类型对象的内部数组。
目录
Member Functions
Construct object (public member function ) | |
Destruct object (public member function ) |
std :: ios_base :: ios_base
protected: ios_base(); ios_base (const ios_base&) = delete;
构造对象
- ios_base对象在构造时具有不确定的值。每个ios_base基类对象都应该通过调用basic_ios :: init来初始化。
- 该类作为基类,因此没有公共构造函数,这就防止了构造该类的对象——只有派生类的对象可以构造。
ios_base也删除了它的复制赋值成员函数。和复制构造函数一样,这个函数也被删除:
ios_base (const ios_base&) = delete; ios_base& operator= (const ios_base&) = delete;
异常安全
- 强有力的保证:如果引发异常,则没有副作用。
std :: ios_base ::〜ios_base
virtual ~ios_base();
销毁对象
- 在对象被销毁之前,所有用成员register_callback注册的回调函数都以erase_event作为第一个参数被调用。
Data races
- 对象被修改。
异常安全
- No-throw保证:从不抛出异常。
获取/设置格式标志(公共成员函数) | |
设置特定的格式标志(公共成员函数) | |
清除特定格式的标志(公共成员函数) | |
获取/设置浮点十进制精度(公共成员函数) | |
获取/设置字段宽度(公共成员函数) |
std::ios_base::flags
get (1) fmtflags flags() const;
set (2) fmtflags flags (fmtflags fmtfl);
获取/设置格式标志
- (1)返回流中当前选择的格式标志。
- (2)为流设置新的格式标志,返回先前的值。
流的格式标志影响数据在特定输入函数中的解释方式,以及特定输出函数如何写入数据。
该函数的第二种形式为流的所有格式标记设置值,覆盖现有值并清除参数中未显式设置的任何标记。要访问单个标记,请参见成员setf 和 unsetf
参数
fmtfl
- 流使用的格式标志。
- ios_base :: fmtflags是位掩码类型。
返回值
- 调用前在流中选择的格式标志。
- ios_base :: fmtflags是位掩码类型。
Data races
- 访问(1)或修改(2)流对象。
- 同时访问同一个流对象可能会导致数据竞争。
异常安全
基本保证:如果抛出异常,则流处于有效状态。
// modify flags
#include <iostream> // std::cout, std::ios
int main () {
std::cout.flags ( std::ios::right | std::ios::hex | std::ios::showbase );
std::cout.width (10);
std::cout << 100 << '\n';
return 0;
}
std :: ios_base :: setf、std::ios_base::unsetf
set (1) fmtflags setf (fmtflags fmtfl);
mask (2) fmtflags setf (fmtflags fmtfl, fmtflags mask);
设置特定的格式标志
(1)设置流的格式标志,其位在fmmtfl中设置,其余的保持不变,相当于
flags(fmtfl|flags())
。(2)设置流的格式标志,其位在fmtfl和mask中都设置,并清除其位在mask中设置但不在fmtfl中设置的格式标志,就像调用flags((fmtfl&mask)|(flags()&~mask))。
两者都返回调用前流的格式标志的值。
流的格式标志影响在某些输入函数中解释数据的方式以及某些输出函数如何写入数据。有关此函数参数的可能值,请参见ios_base::fmtflags。
1)的第一种形式通常用于设置独立的格式标志:boolalpha、showbase、showpoint、showpos、skipws、unitbuf和uppercase,也可以直接用member unset设置。
2)通常用于使用一个字段位掩码作为掩码参数来设置一个选择标志的值:
fmtfl
format flag valuemask
field bitmaskleft, right or internal adjustfield dec, oct or hex basefield scientific or fixed floatfield 参数化操纵器 setiosflags行为与此成员函数(1)的第一种形式类似。
参数:
fmtfl 要设置的格式标志。如果使用第二种语法,只有在fmtfl和mask中设置的位在流的格式标志中设置;在mask中设置但在fmtfl中没有设置的标志被清除 unmask 包含要修改的标志的掩码。 Data races
- 修改流对象。
- 对同一流对象的并发访问可能会导致数据争用。
异常安全:
- 基本保证:如果抛出异常,则流处于有效状态。
void unsetf (fmtflags mask);
清除特定格式的标志
- 清除mask中选择的格式标志。
- 参数化操纵符resetiosflags的行为方式与这个成员函数类似。
参数:
mask 指定要清除的标志的位掩码。这些标志被指定为fmtflags成员类型的标志的组合。 Data races
- 修改流对象。
- 对同一流对象的并发访问可能会导致数据争用。
异常安全:
- 基本保证:如果抛出异常,则流处于有效状态。
// modifying flags with setf/unsetf
#include <iostream> // std::cout, std::ios
int main () {
std::cout.setf ( std::ios::hex, std::ios::basefield ); // set hex as the basefield
std::cout.setf ( std::ios::showbase ); // activate showbase
std::cout << 100 << '\n';
std::cout.unsetf ( std::ios::showbase ); // deactivate showbase
std::cout << 100 << '\n';
return 0;
}
std::ios_base::precision
get (1) streamsize precision() const;
set (2) streamsize precision (streamsize prec);
作用:获取/设置浮点十进制精度
- 1) 返回当前精度。
- 2)将精度设置为给定的精度。返回上一个精度。
浮点精度决定了在表示浮点值的插入操作中要写入的最大数字数。如何解释它取决于floatfield format flag是设置为特定的符号( fixed或scientific)还是未设置(使用默认的符号,不一定等于 fixed或scientific)。
这个十进制精度也可以使用setprecision进行修改。
默认精度由std :: basic_ios :: init建立,为6。
返回值
- 调用前在流中选择 的精度
Data races
- 访问(1)或修改(2)流对象。
- 同时访问同一个流对象可能会导致数据竞争。
异常安全
基本保证:如果抛出异常,则流处于有效状态。
// modify precision
#include <iostream> // std::cout, std::ios
int main () {
double f = 3.14159;
std::cout.unsetf ( std::ios::floatfield ); // floatfield not set
std::cout.precision(5);
std::cout << f << '\n';
std::cout.precision(10);
std::cout << f << '\n';
std::cout.setf( std::ios::fixed, std:: ios::floatfield ); // floatfield set to fixed
std::cout << f << '\n';
return 0;
}
std :: ios_base :: width
get (1) streamsize width() const;
set (2) streamsize width (streamsize wide);
作用:获取/设置字段宽度
1) 返回当前字段的宽度。
2)将字段宽度设置为给定的宽度。返回上一个字段的 fill。
字段宽度决定要在某些输出表示形式中写入的最小字符数。如果表示的标准宽度小于字段宽度,表示将在格式标志adjustfield确定的点用填充字符填充(left, right or internal)
可以通过调用成员函数fill来检索或更改填充字符。
可以通过调用成员函数flags或setf来修改格式标记调整字段,方法是插入以下操作符之一: left, right 和 internal,或者插入参数化操作符setiosflags.。
也可以通过 setw修改字段宽度。
返回:
调用前字段宽度的值。
// field width
#include <iostream> // std::cout, std::left
int main () {
std::cout << 100 << '\n';
std::cout.width(10);
std::cout << 100 << '\n';
std::cout.fill('x');
std::cout.width(15);
std::cout << std::left << 100 << '\n';
return 0;
}
Imbue语言环境(公共成员函数) | |
获取当前语言环境(公共成员函数) |
std :: ios_base :: imbue
locale imbue (const locale& loc);
作用:将loc作为流的新语言环境
- 将loc与流关联起来,作为新的locale对象,与语言环境敏感的操作一起使用。
- 在此之前,该函数以imbue_event作为第一个参数,调用所有通过成员register_callback注册的函数。
- 标准流类不继承这个成员,而是继承调用这个函数的basic_ios::imbue,但也会将区域设置注入到相关的流缓冲区(如果有的话)。
返回值:调用前与流关联的locale 对象。
// imbue example
#include <iostream> // std::cout
#include <locale> // std::locale
int main()
{
std::locale mylocale(""); // get global locale
std::cout.imbue(mylocale); // imbue global locale
std::cout << 3.14159 << '\n';
return 0;
}
std::ios_base::getloc
locale getloc() const;
作用:返回与流关联的当前语言环境。
获取可扩展数组的新索引[静态] (公共静态成员函数) | |
获取可扩展数组的整数元素(公共成员函数) | |
获取可扩展数组的指针元素(公共成员函数) |
std :: ios_base :: xalloc
static int xalloc();
作用:获取可扩展数组的新索引[静态]
内部可扩展数组是long(如果使用成员iword访问)或void*(如果使用成员pword访问)类型的对象的通用数组。
返回值:
- 可以与成员iword或成员pword一起使用的新索引。
Data races:
- 同时调用这个函数可能会引入数据竞争。
异常安全:
- 强保证:如果抛出异常,则任何流中都不会发生更改。
#include <iostream>
template<class charT, class traits = std::char_traits<charT> >
class mystream : public std::basic_ostream<charT, traits>
{
public:
static const int xindex;
mystream(std::basic_ostream<charT, traits>& ostr) :
std::basic_ostream<charT, traits>(ostr.rdbuf())
{
this->pword(xindex) = this;
}
void myfn()
{
*this << "[special handling for mystream]";
}
};
// each specialization of mystream obtains a unique index from xalloc()
template<class charT, class traits>
const int mystream<charT, traits>::xindex = std::ios_base::xalloc();
// This I/O manipulator will be able to recognize ostreams that are mystreams
// by looking up the pointer stored in pword
template<class charT, class traits>
std::basic_ostream<charT,traits>& mymanip(std::basic_ostream<charT,traits>& os)
{
if (os.pword(mystream<charT,traits>::xindex) == &os)
static_cast<mystream<charT,traits>&>(os).myfn();
return os;
}
int main()
{
std::cout << "cout, narrow-character test " << mymanip << '\n';
mystream<char> myout(std::cout);
myout << "myout, narrow-character test " << mymanip << '\n';
std::wcout << "wcout, wide-character test " << mymanip << '\n';
mystream<wchar_t> mywout(std::wcout);
mywout << "mywout, wide-character test " << mymanip << '\n';
}
std :: ios_base :: iword
long& iword( int index );
作用:获取可扩展数组的整数元素
#include <iostream>
// custom manipulator with per-stream static data:
std::ostream& Counter (std::ostream& os) {
const static int index = os.xalloc();
return os << ++os.iword(index);
}
int main()
{
std::cout << Counter << ": first line\n";
std::cout << Counter << ": second line\n";
std::cout << Counter << ": third line\n";
// cerr has its own count
std::cerr << Counter << ": error line\n";
}
#include <iostream>
#include <string>
struct Foo {
static int foo_xalloc;
std::string data;
Foo(const std::string& s) : data(s) {}
};
// allocates the iword storage for use with Foo objects
int Foo::foo_xalloc = std::ios_base::xalloc();
// This user-defined operator<< prints the string in reverse if the iword holds 1
std::ostream& operator<<(std::ostream& os, Foo& f)
{
if(os.iword(Foo::foo_xalloc) == 1)
return os << std::string(f.data.rbegin(), f.data.rend());
else
return os << f.data;
}
// This I/O manipulator flips the number stored in iword between 0 and 1
std::ios_base& rev(std::ios_base& os)
{
os.iword(Foo::foo_xalloc) = !os.iword(Foo::foo_xalloc);
return os;
}
int main()
{
Foo f("example");
std::cout << f << '\n' << rev << f << '\n' << rev << f << '\n';
}
std :: ios_base :: pword
void *&pword(int idx);
作用:获取可扩展数组的指针元素
// pword example
#include <iostream> // std::ios, std::cout, std::cerr, std::clog
const int name_index = std::ios::xalloc();
// stores pointer in extensible array:
void SetStreamName (std::ios& stream, const char* name) {
stream.pword(name_index) = const_cast<char*>(name);
}
// custom manipulator that uses stored pointer:
std::ostream& StreamName (std::ostream& os) {
const char* name = static_cast<const char*>(os.pword(name_index));
if (name) os << name;
else os << "(unknown)";
return os;
}
int main()
{
SetStreamName(std::cout, "standard output stream");
SetStreamName(std::cerr, "standard error stream");
std::cout << StreamName << '\n';
std::cerr << StreamName << '\n';
std::clog << StreamName << '\n';
return 0;
}
注册事件回调函数(公共成员函数) | |
设置每个输入输出操作后是否将标准C++流同步到标准C流 |
std :: ios_base :: register_callback
void register_callback(event_callback fn,int索引);
作用:
- 注册一个用户定义的函数,该函数将被imbue()、std::basic_ios::copyfmt()和~ios_base()调用。
- 每个注册的回调函数每次都会被调用:事件类型(event类型的值)作为它的第一个参数传递,可以用来区分调用者。
- 如果注册了多个回调函数,则会以注册的相反顺序全部调用它们。
- 用户定义的回调函数不允许引发异常。
- 一旦注册,回调就无法取消注册:在其整个生命周期中,它仍是流对象的一部分。如果需要更改回调的行为,则可以通过iword()或pword()进行控制。
如果同一功能被多次注册,则将被多次调用。
与回调一起存储的整数值通常是从xalloc()获得的索引
Data races:
- 同时调用这个函数可能会引入数据竞争。
异常安全
- 基本保证:如果引发异常,则流处于有效状态。
// stream callbacks
#include <iostream> // std::cout, std::ios_base
#include <fstream> // ofstream
void testfn (std::ios::event ev, std::ios_base& stream, int index)
{
switch (ev)
{
case stream.copyfmt_event:
std::cout << "copyfmt_event\n"; break;
case stream.imbue_event:
std::cout << "imbue_event\n"; break;
case stream.erase_event:
std::cout << "erase_event\n"; break;
}
}
int main () {
std::ofstream filestr;
filestr.register_callback (testfn,0);
filestr.imbue (std::cout.getloc());
return 0;
}
std :: ios_base :: sync_with_stdio
bool sync_with_stdio(bool sync = true);
作用:设置每个输入输出操作后是否将标准C++流同步到标准C流
- 如果流是同步的,程序可以混合iostream操作和stdio操作,并且它们的可观察效果保证与线程中使用的顺序相同。
- 并发访问同步流(即该函数返回true的流)从不引入数据竞争:字符是单独读写的,尽管没有进一步保证线程之间的顺序。这可能会导致线程之间的交错字符,除非程序强制执行整个操作的适当同步。
Data races:
- 同时调用这个函数可能会引入数据竞争。
异常安全
- 基本保证:如果引发异常,则流处于有效状态。
#include <iostream>
#include <cstdio>
int main()
{
std::ios::sync_with_stdio(false);
std::cout << "a\n";
std::printf("b\n");
std::cout << "c\n";
}
Member types
表示事件类型的类型(公共成员类型) | |
event_callback | 事件回调函数类型(公共成员类型) |
流格式标志的类型(公共成员类型) | |
流状态标志的类型(公共成员类型) | |
流打开模式标志的类型(公共成员类型) | |
流搜索方向标志的类型(公共成员类型) |
std :: ios_base :: event
enum event {erase_event, imbue_event, copyfmt_event};
指定事件类型
- 指定传递给register_callback()在特定事件上注册的函数的事件类型。定义了以下常量:
Constant 事件触发 erase_event
调用 ~ios_base() or basic_ios::copyfmt() (在复制成员之前) imbue_event
调用 ios_base :: imbue (就在函数返回之前)。 copyfmt_event
调用 basic_ios::copyfmt() (在复制成员之后,但在复制异常设置之前)
std :: ios_base :: event_callback
typedef void (*event_callback)(event type, ios_base& ios, int index);
函数回调的类型,可以使用register_callback()注册,在特定事件上调用。
- type是ios_base::event类型的值,它指示了将调用这个回调的事件的类型。
- 当回调函数被std::ios_base和std::basic_ios成员函数调用时,this作为参数传递。
- index是注册函数时传递给register_callback()的用户提供的值。
std :: ios_base :: seekdir
typedef /*implementation defined*/ seekdir; static constexpr seekdir beg = /*implementation defined*/ static constexpr seekdir end = /*implementation defined*/ static constexpr seekdir cur = /*implementation defined*/
指定文件搜索方向类型。定义了以下常量:
Constant Explanation beg 流的开始 end 流的结尾 cur
流位置指示器的当前位置
#include <iostream>
#include <string>
#include <sstream>
int main()
{
std::istringstream in("Hello, World!");
std::string word1, word2, word3, word4, word5;
in >> word1;
in.seekg(0, std::ios_base::beg); // <- rewind
in >> word2;
in.seekg(1, std::ios_base::cur); // -> seek from cur pos toward the end
in >> word3;
in.seekg(-6, std::ios_base::cur); // <- seek from cur pos (end) toward begin
in >> word4;
in.seekg(-6, std::ios_base::end); // <- seek from end toward begin
in >> word5;
std::cout << "word1 = " << word1 << '\n'
<< "word2 = " << word2 << '\n'
<< "word3 = " << word3 << '\n'
<< "word4 = " << word4 << '\n'
<< "word5 = " << word5 << '\n';
}
std::ios_base::iostate
typedef /*implementation defined*/ iostate; static constexpr iostate goodbit = 0; static constexpr iostate badbit = /*implementation defined*/ static constexpr iostate failbit = /*implementation defined*/ static constexpr iostate eofbit = /*implementation defined*/
流状态标志的类型
Constant Explanation goodbit no error badbit 不可恢复的流错误 failbit 输入/输出操作失败(格式或提取错误) eofbit 相关的输入序列已到达文件末尾 ---
std :: ios_base :: fmtflags
typedef /*implementation defined*/ fmtflags; static constexpr fmtflags dec = /*implementation defined*/ static constexpr fmtflags oct = /*implementation defined*/ static constexpr fmtflags hex = /*implementation defined*/ static constexpr fmtflags basefield = dec | oct | hex; static constexpr fmtflags left = /*implementation defined*/ static constexpr fmtflags right = /*implementation defined*/ static constexpr fmtflags internal = /*implementation defined*/ static constexpr fmtflags adjustfield = left | right | internal; static constexpr fmtflags scientific = /*implementation defined*/ static constexpr fmtflags fixed = /*implementation defined*/ static constexpr fmtflags floatfield = scientific | fixed; static constexpr fmtflags boolalpha = /*implementation defined*/ static constexpr fmtflags showbase = /*implementation defined*/ static constexpr fmtflags showpoint = /*implementation defined*/ static constexpr fmtflags showpos = /*implementation defined*/ static constexpr fmtflags skipws = /*implementation defined*/ static constexpr fmtflags unitbuf = /*implementation defined*/ static constexpr fmtflags uppercase = /*implementation defined*/
指定可用的格式标志。它是一个BitmaskType。定义了以下常量:
Constant Explanation dec 对整数I/O使用十进制基数: see std::dec oct 对整数I/O使用八进制基数: see std::oct hex 对整数I/O使用十六进制基数: see std::hex basefield dec|oct|hex. 用于屏蔽操作 left 左调整(向右侧添加填充字符):: see std::left right 右调整(向左侧添加填充字符): see std::right internal internal adjustment (在内部指定点上增加填充字符): see std::internal adjustfield left|right|internal. 用于屏蔽操作 scientific 用科学计数法写浮点值: see std::scientific fixed 用定点表示法写浮点值:see std::fixed floatfield scientific|fixed. 用于屏蔽操作 boolalpha 以字母字符串( true
和false
)读取/写入bool元素。: see std::boolalphashowbase 生成一个指示整数输出数字基数的前缀,需要货币I / O中的货币指示符: see std::showbase showpoint 无条件生成浮点数输出的小数点字符:see std::showpoint showpos 在非负数值前加一个加号(+): see std::showpos skipws 在某些输入操作之前跳过前导空格:see std::skipws unitbuf 在某些输出操作中, 将某些小写字母替换为大写字母: see std::unitbuf uppercase 在某些输出操作中, 将某些小写字母替换为大写字母:see std::uppercase --
#include <iostream>
int main()
{
int num = 150;
// using fmtflags as class member constants:
std::cout.setf(std::ios_base::hex, std::ios_base::basefield);
std::cout.setf(std::ios_base::showbase);
std::cout << num << '\n';
// using fmtflags as inherited class member constants:
std::cout.setf (std::ios::hex , std::ios::basefield);
std::cout.setf (std::ios::showbase);
std::cout << num << '\n';
// using fmtflags as object member constants:
std::cout.setf(std::cout.hex, std::cout.basefield);
std::cout.setf(std::cout.showbase);
std::cout << num << '\n';
// using fmtflags as a type:
std::ios_base::fmtflags ff;
ff = std::cout.flags();
ff &= ~std::cout.basefield; // unset basefield bits
ff |= std::cout.hex; // set hex
ff |= std::cout.showbase; // set showbase
std::cout.flags(ff);
std::cout << num << '\n';
// not using fmtflags, but using manipulators:
std::cout << std::hex << std::showbase << num << '\n';
}
Member classes
流异常的基类(公共成员类) | |
初始化标准流对象(公共成员类) |
std::ios_base::failure
类std :: ios_base :: failure定义输入/输出库中的函数在失败时引发的异常对象。
std :: ios_base :: failure可以定义为std :: ios_base的成员类,也可以定义为具有相同功能的另一个类的同义词(typedef)
---
#include <iostream>
#include <fstream>
int main()
{
std::ifstream f("doesn't exist");
try {
f.exceptions(f.failbit);
} catch (const std::ios_base::failure& e)
{
std::cout << "Caught an ios_base::failure.\n"
<< "Explanatory string: " << e.what() << '\n'
<< "Error code: " << e.code() << '\n';
}
}
std::ios_base::Init
成员常量
流具有成员常量,其中可能包含成员类型fmtflags、iostate、openmode和seekdir的值(有关详细信息,请参阅每种类型的描述)。
https://en.cppreference.com/w/cpp/io/ios_base/iostate