格式标志
格式标志可以控制输入输出的格式,比如是否在正数前加+号,用八进制、十进制、十六进制来显示数据等。
以下是访问格式标志的成员函数(定义在ios_base类中)
成员函数 | 意义 |
---|---|
setf(flags) | 增加标志,返回修改前的所有标志 |
setf(flags, mask) | 增加标志,mask参数存放的标志则被清除,返回修改前的所有标志 |
unsetf(flags) | 清除标志 |
flags() | 返回当前所有标志 |
flags(flags) | 将flags设为新的格式标志,返回修改前的所有标志 |
copyfmt(stream) | 从stream中复制所有格式定义 |
说明:
setf(flags, mask)
举例: std::cout.sef( std::ios::hex, std::ios::basefield);
其中标志位ios::basefield是hex|oct|dec三个标志的组合,其它标志位定义参考如下,
static const _Fmtflags skipws = (_Fmtflags)_IOSskipws;
static const _Fmtflags unitbuf = (_Fmtflags)_IOSunitbuf;
static const _Fmtflags uppercase = (_Fmtflags)_IOSuppercase;
static const _Fmtflags showbase = (_Fmtflags)_IOSshowbase;
static const _Fmtflags showpoint = (_Fmtflags)_IOSshowpoint;
static const _Fmtflags showpos = (_Fmtflags)_IOSshowpos;
static const _Fmtflags left = (_Fmtflags)_IOSleft;
static const _Fmtflags right = (_Fmtflags)_IOSright;
static const _Fmtflags internal = (_Fmtflags)_IOSinternal;
static const _Fmtflags dec = (_Fmtflags)_IOSdec;
static const _Fmtflags oct = (_Fmtflags)_IOSoct;
static const _Fmtflags hex = (_Fmtflags)_IOShex;
static const _Fmtflags scientific = (_Fmtflags)_IOSscientific;
static const _Fmtflags fixed = (_Fmtflags)_IOSfixed;
static const _Fmtflags boolalpha = (_Fmtflags)_IOSboolalpha;
static const _Fmtflags _Stdio = (_Fmtflags)_IOS_Stdio;
static const _Fmtflags adjustfield = (_Fmtflags)(_IOSleft
| _IOSright | _IOSinternal);
static const _Fmtflags basefield = (_Fmtflags)(_IOSdec
| _IOSoct | _IOShex);
static const _Fmtflags floatfield = (_Fmtflags)(_IOSscientific
| _IOSfixed);
为了与IO操作符<<、>>配合使用,实现了以下两个操控器(带参数)来设置格式标志
操控器 | 意义 |
---|---|
std::setiosflags(flags) | 将flags设为格式标志(调用setf(flags) ) |
std::resetiosflags(mask) | 清除mask所标识的一组标志(调用setf(0, mask) ) |
例如:
cout << std::resetiosflags( ios::basefield ) << std::setiosflags( ios::hex ) << 15 << endl;
输出:
f
布尔值 的IO格式
由标志boolalpha
来控制,若设置了此标志,便以文字表示,否则又数据表示,缺省的未被设立。注:此标志被设立,就一直生效,除非清除此标志
为了与操作符<<、>>配合使用,实现了以下操控器
操控器 | 意义 |
---|---|
std::boolalpha | 设立标志ios::boolalpha |
std::noboolalpha | 清除标志ios::boolalpha |
例如以下
cout << std::boolalpha << true << endl;
cout << false << endl;
输出的为:
true
false
字段宽度、填充字符、位置对齐
字段宽度、填充字符由成员函数控制,位置对齐方式则由格式标志来控制。
成员函数 | 意义 |
---|---|
width() | 返回当前字符宽度 |
width(val) | 设置当前字符宽度,并返回先前的字符宽度 |
fill() | 返回当前填充字符 |
fill(c) | 设置当前填充字符,并返回先前填充字符 |
以上表格中,函数width
调用后的作用为一次性的,即执行了任意格式化IO操作后,就会恢复width的值为缺省状态。而fill设置的则一直生效,除非重新设置。例如:
//以^符号填充
cout.fill( '^' );
cout.width( 4 );
cout << 1 << endl;
//恢复默认width
cout << 1 << endl;
位置对齐格式标志如下:
掩码 | 标志 | 意义 |
---|---|---|
ios::adjustfield | ios::left | 左对齐 |
ios::right | 右对齐 | |
ios::internal | 符号靠左对齐,数值靠右对齐 | |
None | 右对齐(默认) |
同样,也提供了对应的操控器
- std::setw(val),相当于widht(val)
- std::setfill(c),相当于fill(c)
- std::left,相当于setf( ios::left, ios::adjustfield)
- std::right,相当于setf(ios::left, ios::adjustfield)
- std::internal,相当于setf(ios::internal, ios::adjustfield)
- -
正号、大写字符
由格式标志: ios::showpos、ios::uppercase来控制。ios::showpos被设置了,则在正数前显示+号,ios::uppercase标志被设置了,则针对十六进制、科学记号等的字母就以大写的格式输出,对字符串是不会有影响的。
同样,也提供了对应的操控器
- std::showpos
- std::noshowpos
- std::uppercase
- std::nouppercase
注:此两个标志被设立,就一直生效,除非清除此标志
数值进制
由格式标志控制
- ios::oct,以八进制进行读写
- ios::dec,以十进制进行读写
- ios::hex,以十六进制进行读写
- none,以十进制输出;读取时则视起始字符而定
- ios::showbase, 若被设置,则显示数字的进制,八进制以0开头,十六进制则以0x开头
同样的,也有相应的操作器
- std::oct
- std::dec
- std::hex
- std::showbase
- std::noshowbase
注:此四个标志被设立,就一直生效,除非清除此标志
浮点数表示法
浮点数表示由格式标志控制
- ios::fixed,使用小数表示法
- ios::scientific,使用科学计数表示法
- None,使用上述两者中最适合者(默认)
- ios::showpoint,总是书写小数点
精度控制成员函数
- precision(),返回当前浮点数精度
- precision(val),设置浮点数精度
对应操控器
- std::showpoint
- std::noshowpoint
- std::setprecision(val)
- std::fixed
- std::scientific
注:以上标志被设立,就一直生效,除非清除此标志,精度被设置,也一样
一般性格式定义
格式标志
- ios::skipws,调用>>读取数值时,跳过起始空格,默认设置此标志
- ios::unitbuf,每次输出后,清空output缓冲区
操控器
- std::skipws
- std::noskipws
- unitbuf
- nounitbuf
注:以上标志被设立,就一直生效,除非清除此标志
国际化
ios_base类定义了数个成员函数来支持国际化
- imbue(loc),设置locale对象
- getloc(),返回当前locale对象
- widen(c),将char型别c转换成stream字符集中的
- narrow(c, def),widen的逆操作
总结
- 格式标志
ios::width
是一次性的 ,即执行了任意格式化IO操作后,就会恢复width的值为缺省状态 - std::ws,这个操控器也是一次性的,文章http://blog.csdn.net/s634772208/article/details/72852975介绍了此操控器
- 注意
std::skipws
与std::ws
的区别,前者是表示调用>>时,跳过起始空格,后者读取时忽略空格,并且是一次性的。
以下演示std::noskipws
的用法:
//此处若输入(_表空格):_1space
//则啥也不输出,因为>>读取字符串时是以空格来判断是否结束的
//第一个空格没被跳过,表示结束读取,因为啥也没读到,流被设置读取失败
std::string strTemp;
std::cin >> std::noskipws;
while( cin >> strTemp )
{
cout << strTemp << endl;
}
//此处会一个字符一个字符的读取,空格也会被读取
//若输入: _a_b
//则输出:
//_
//a
//_
//b
char c;
cin >> std::noskipws;
while( cin >> c )
{
if ( c == '\n')
{
continue;
}
cout << c << endl;
}