1.10 操纵器
C和C++代码精粹
当标识符 endl出现在一个输出流中时,一个换行字符就被插入并且流被刷新。标识符endl是操纵器的一个例子,即为了副效应而插入到流的一个对象。在〈iostream〉中被声明的系统预定义的操纵器列于表 1.3中。程序清单1.11里的程序在功能上与程序清单1.10的程序等价,但它是用操纵器来代替显式调用setf函数。操纵器经常可以使代码更为高效。
程序清单1.11 用操纵器改变数据基数
// base2.cpp: 显示整数的基数
// (使用操纵器)
#include <iostream>
using namespace std;
main()
{
int x, y, z;
cout << "输入三个整形数:”;
cin >> x >> y >> z;
cout << x << ',' << y << ',' << z << endl;
//在不同基数中显示
cout << dec << x << ','
<< oct << y << ','
<< hex << z << endl;
//显示基数前缀
cout.setf(ios::showbase);
cout << dec << x << ','
<< oct << y << ','
<< hex << z << endl;
}
其他的操纵器带有参数(见表1.4)。在程序清单1.12中的程序是用setw(n)操纵器直接在插入序列里设置输出宽度,这样就不需要单独调用width。ios::width区域是特殊的:它在每次的插入后立即重置为0。当iso::width是0时,值以所需的最少字符数打印,通常,即使它们的空间不够,数字也不会被删掉。
表1.4 参数化的操纵器(iomanip)
程序清单1.12 利用setw函数设置输出域宽
// adjust.cpp: 调整输出
#include <iostream>
#include <iomanip>
using namespace std;
main()
{
cout << '|' << setw(10) << "hello" << '|' << endl;
cout.setf(ios::left,ios::adjustfield);
cout << '|' << setw(10) << "hello" << '|' << endl;
cout.fill('#');
cout << '|' << setw(10) << "hello" << '|' << endl;
}
//输出:
| hello|
|hello |
|hello#####|
当然你可以用操纵器
…<<setfill('#')<<…
来替换语句
cout.fill('#');
但在这种情况下,这样做似乎很不方便。
提取器通常忽视宽度设置,但C风格的字符串输入是个例外。在对字符数组进行提取操作之前应该先将域宽设置为字符数组的大小,以避免数据溢出。当处理输入行
nowisthetimeforall
时,程序清单1.13程序将输出:
nowisthet,im,eforall
应记住的是,编译器将空白字符默认为分隔符,所以如果输入为:
now is the time for all
那么输出将是:
now,is,the
程序清单1.13 控制输入字符串宽度
// width.cpp: 控制输入字符串的宽度
#include <iostream>
#include <iomanip>
using namespace std;
main()
{
char s1[10], s2[3], s3[20];
cin >> setw(10) >> s1
>> setw(3) >> s2
>> s3;
cout << s1 << ',' << s2 << ',' << s3 << endl;
}
输入输出流也支持新的布尔数据类型(bool),以及格式标识和用于数字或字母文本的操纵器:
bool b=true;
cout<<b<<endl; //打印“1”
cout.setf(ios::boolalpha); //或仅插入操纵器boolalpha
cout<<b<<endl; //打印“true”
你可以通过简单定义一个将流引用作为参数并返回相同引用的函数来建立一个自己的操纵器。例如,下面是一个ASCII码控制铃声的操纵器,当将它插入在任何输出流中时可以发出铃声:
//响铃操纵器
#include <iostream>
ostream& beep(ostream& os)
{
os<<char(7);//ASCII 响铃
return os;
}
使用时,只需插入:
`cout<<…<<beep<<…`
本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。