《C和C++代码精粹》——1.10 操纵器-阿里云开发者社区

开发者社区> 开发与运维> 正文

《C和C++代码精粹》——1.10 操纵器

简介:

本节书摘来自异步社区出版社《C和C++代码精粹》一书中的第1章,第1.10节,作者: 【美】Chuck Allison,更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.10 操纵器

C和C++代码精粹
当标识符 endl出现在一个输出流中时,一个换行字符就被插入并且流被刷新。标识符endl是操纵器的一个例子,即为了副效应而插入到流的一个对象。在〈iostream〉中被声明的系统预定义的操纵器列于表 1.3中。程序清单1.11里的程序在功能上与程序清单1.10的程序等价,但它是用操纵器来代替显式调用setf函数。操纵器经常可以使代码更为高效。

表1.3 简单的操纵器(〈iostream〉)
image
image

程序清单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)

image

程序清单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<<…`

本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章