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

1.10 操纵器

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

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

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

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

时间: 2024-10-27 20:26:12

《C和C++代码精粹》——1.10 操纵器的相关文章

《C和C++代码精粹》——2.10 指针和多维数组

2.10 指针和多维数组 C和C++代码精粹实际上,在C++中没有多维数组!至少对多维数组没有直接的支持.人们通常把一个一维数组看作一个向量,把一个二维数组看作一个表或者矩阵,把一个三维数组看作一个长方体.然而,数组的几何模型使明智地使用高维数组变得很困难,取而代之的是C++支持"数组的数组"的概念.例如,如果一个一维的整型数组为 int a[4]={0,1,2,3}; 它是一个有索引的整数集合: 我们通常把它描述成一个向量: 对一个二维整型数组,如: int a[3][4]={{0,

《C和C++代码精粹》导读

前言 C和C++代码精粹 本书适合于那些C和C++的职业程序员.假如你已熟悉这两种语言的语法和基本结构,这本书能够为你创建有效的.实用的程序提供实践性的指导.每一个代码范例或程序范例均标明行之有效的用法和技术,这些用法和技术对C/C++这两种重要编程语言的性能发挥起着重要的作用. 对于那些希望在工作中加强自身技术和提高效率的人来说,本书可以算是一本经验之谈.尽管目前人们对面向对象模式的推崇到了白热状态(本书也包括这方面的丰富内容),可是我没有理由不对C++的基础-C表示尊崇.我发现太多的程序开发

《C和C++代码精粹》——2.7 指针和一维数组

2.7 指针和一维数组 C和C++代码精粹 在程序清单2.7中,会注意到在传递数组 s 时并没有使用它的地址,这是因为C和C++在大多数表达式中把数组名转换成指向它第一个元素的指针.自1984年以来,我已经向成百上千的学生讲授了C和C++,我注意到了指针和数组,特别是指针和多维数组之间的关系造成很多迷惑. 这样说似乎很奇怪,但是C++确实不支持数组,至少C++不像支持第一类数据类型如整型或者甚至结构体那样支持数组.考虑以下的语句: int i=1,j; int a[4]={0,1,2,3},b[

《C和C++代码精粹》——第 1 章 更好的C1.1 两种语言简述

第 1 章 更好的C C和C++代码精粹本文仅用于学习和交流目的,不代表异步社区观点.非商业转载请注明作译者.出处,并保留本文的原始链接. 1.1 两种语言简述 C和C++代码精粹20世纪80年代初期,C++起源于AT&T,称为带类的 C,当时Bjarne Stroustrup试图用Simula-67编写仿真程序."类"在Simula中是表示用户定义类型的术语,编写好的仿真程序的关键是能够定义对象反映现实世界.除了把类加到C中使其成为最快的过程语言外,还有什么更好的方法可以得到

《C和C++代码精粹》——1.8 标准流

1.8 标准流 C和C++代码精粹C++中有4个预定义的流:cin(标准输入),cout(标准输出),cerr(标准错误),clog(标准错误).除了cerr外其余都是全缓冲流.就像stderr一样,cerr的行为好象是非缓冲的,但事实上它是单元缓冲的,也就是说它在处理完每一个对象而不是每一个字节后会自动清除缓冲.例如,带有单元缓冲的语句: cerr<<"hello":缓冲处理5个字符,然后清除缓冲区.一个非缓冲处理的流会立即发送每个字符到它的最终目的地. 程序清单1.5

《C和C++代码精粹》——1.3 类型系统

1.3 类型系统 C和C++代码精粹理解C++最重要的部分,也许就是它对于类型安全(type safety)的贡献.上面所提及的其他面向对象语言实质上是无类型的,或最多也只能说是弱类型的,因为它们主要是在程序运行期间执行错误检查,换句话说,C++要求声明每个程序实体的类型,并且在编译期内它要一丝不苟地检查相同用法.正是类型安全而不是其他别的特点,使C++成为更好的C,成为常用编程工作的最合理的选择.类型系统的特征包括函数原型.类型安全连接.新风格的类型转换.运行期类型识别(RTTI)(有关类型转

《C和C++代码精粹》——1.18 C的兼容性

1.18 C的兼容性 C和C++代码精粹为了提供强类型检查和面向对象, C++不得不在一些语言方面与C不同.如果要把C++作为更好的C使用,就必须留意两种语言间的不同特性. 程序清单1.18 说明复数模板 #include <iostream> #include <complex> using namespace std; main() { complex<double> x(1.0, 2.0), y(3.0, 4.0); cout << "x +

《C和C++代码精粹》——2.15 小结

2.15 小结 C和C++代码精粹C和C++仅仅与那些使用它们的人一样危险.指针是地址.可以将任何一个指针赋值成void*.注意区分一个const指针和一个指向const的指针.p±n = =(char)p±n sizeof (*p).p-q = = ±n .*(a+i) = = a [i].除非在sizeof和&的上下文中,否则一个数组名即是指向它第一个元素的指针.没有多维数组,只有数组的数组.仅是指针的存在并不要求它所引用的类型的实现的有效性(这是一个不完全类型).如果理解了这些概念,你就正

《C和C++代码精粹》——2.2 基础

2.2 基础 C和C++代码精粹除了寄存器变量以外,程序中的所有对象都存储在内存中的某处,"某处"有一个地址,在开发平台上内存的每个字节的序号按顺序从0开始,简单地说,地址就是一个字节的顺序号.下面的程序说明了如何找到程序变量的地址: // address.cpp #include <cstdio> #include <iostream> using namespace std; main() { int i = 7, j = 8; printf("i