首页 理论教育 大道至简:C++STLstream精解

大道至简:C++STLstream精解

时间:2023-10-25 理论教育 版权反馈
【摘要】:类basic_is-tream< >和类basic_ostream< >重载了它们,使其成为标准的I/O操作符。C++ STL使用相同的机制提供string、bitset及complex等类型的output操作符。stream input操作符被定义为:将读入的数值存储在第二参数。最重要的是设立stream的格式化选项,以字符串形式对布尔量进行IO操作。C++的IOStream库使用操作符、标志和成员函数支持类似的格式化显示。针对istream和ostream的操控符分别在<istream>和<ostream>中给出,并在<iostream>中也同时给出。

大道至简:C++STLstream精解

C/C++的运算符“>>”和“<<”,分别用于“位左移”和“位右移”。类basic_is-tream< >和类basic_ostream< >重载了它们,使其成为标准的I/O操作符。本节主要介绍output操作符、input操作符、特殊型别的IO、操作符的格式化等内容。

1.output操作符

output操作符的声明形式有以下4种:

basic_ostream(ostream和wostream均可)将“<<”定义为output操作符,并对所有基本数据类型型别均进行了重载,包括char∗、void∗、bool等。stream将其output操作符定义为:把第二参数发送到相应的stream中。操作符“<<”会被重载,第二参数可以是任意型别。C++ STL使用相同的机制提供string、bitset及complex等类型的output操作符。前面章节已经大量使用了“<<”符号用于输出,此处不再赘述。输出机制的可扩展性使程序员的自定义型别能够天衣无缝地融入输入/输出系统中,“<<”和C语言的printf()输出机制相比,是跨越式进步。程序员在输出数据时,不仅仅局限于标准型别,还包括自定义型别。

操作符“<<”不仅可以输出单个对象,还可以输出多个对象,即使用“<<”可以将需要输出的数据编写成一串,由“<<”运算符按由左到右的次序依次输出。

2.input操作符

input操作符的声明形式如下:

basic_istream将“>>”定义为input操作符。和basic_ostream类似,basic_istream对基本的数据类型型别(char∗、void∗和bool)重载了操作符“>>”。stream input操作符被定义为:将读入的数值存储在第二参数。参数的传递方向是箭头方向。

和“<<”同样,程序员可以对任意型别重载input操作符,并串联使用它们。

3.特别型别I/O

标准I/O操作符还定义了bool、char和void型别的输入和输出。“>>”和“<<”还可以运用于自定义类型对象的输出和输入。

默认情况下,布尔值的读取和输出均以数字的形式出现。在C语言中,true代表“真”或“1”,false代表“假”或“0”。如果读入的数值既非1也非0,即被认为是错误的。此时ios类可能会抛出相应的异常。

最重要的是设立stream的格式化选项,以字符串形式对布尔量进行IO操作。这目前仍然是国际化的议题,多数情况下采用字符串“true”和“false”。并且在不同的国家,不同的语系,存在不同的形式。特殊的localeobjects会使用相应的字符串。

对于char和wchar_t,经由操作符“>>”读取一个char或wchar_t字符时,通常开头的空格会被去掉,如果需要保留读入的所有字符包括空格),需要清除skipws标志或利用成员函数get()。

对于char∗型的C字符串,在读入过程中,起始的空格会被跳过,一直到非空格或文件结束为止。如果需要保留起始的空格,可由标志skipws控制。以上阐述说明,使用C语言读入的字符串最大长度远超过80个字符。因此,C++语言的string型对象(或容器)可容纳足够的字符。使用string代替char∗可使程序更轻松、更安全;另外,string还提供更便捷的函数(getline()),用以实现逐行读入数据。程序员应尽量使用string,以提高编程效率

对于void∗,操作符“<<”和“>>”为指针的打印和读入提供了方便。当数据类型型别为void∗的参数被传递至output操作符(“<<”)时,其地址将被输出,而不是输出指针指向的内容。

例7-1

例7-1输出结果为:

借助input操作符(“>>”)读入地址,需要注意的是,地址是临时性的,同一对象的地址在程序每次执行时可能会不同。地址的输出和输入的可能应用:交换对象地址或共享内存。

对于stream Buffers(串流缓冲区),操作符“>>”和“<<”可以直接用于读写或改写串流缓冲区,运用C++类IOstream实现文件复制的最快途径。

自定义型别在使用时是比较方便的。但由于需要考虑所有可能的格式和错误条件,因此需要付出更多努力。对于自定义型别扩展标准I/O机制,后面会有更复杂的讨论。(www.xing528.com)

4.操作符的格式化

前面的章节已经涉及了在输出时需要使用cout的内容。使用cout时,可以使用很多种格式显示数字。C++的IOStream库使用操作符、标志和成员函数支持类似的格式化显示。对于简单的数值列表显示,cout对象会工作得非常好。还可以使用标准IOStream系统所提供的格式化,以多种方式显示输出。

5.带参数的操作符

为便于程序员可以不直接以标志位的方式处理流的状态,STL还提供了部分函数。这些函数用于操控类似状态,其实质是在读写对象之间插入一个修改状态的操作。

例如,flush函数可以显式地刷新输出缓冲区。

例如,noskipws操控符可以在输入时不省略前面的空格。

在上述语句中,noskipws可以代替cin.unsetf(ios_base::skipws)函数。

下面主要讲述带参数的操控符。

带参数的操控符非常有用。例如cout.precision(int np)。该函数的执行结果是使用4位精度输出随后输出的变量或其他类型对象。

上述代码的输出结果为:

6.标准I/O操作符

STL针对各种各样的格式状态和状态变化提供了一批操控符。标准I/O操控符定义在名称空间std中。针对ios_base的操控符由<ios>给出。针对istream和ostream的操控符分别在<istream>和<ostream>中给出,并在<iostream>中也同时给出。其他更复杂的标准操控符则由头文件<iomanip>给出。

例7-2

如果使用带参数的操控符,需要加括号。如果要使用带参数的标准操控符,应包含头文件<iomanip>。

例如,

上述代码的输出结果为:

7.用户自定义操作符

程序员按照标准的风格使用各自的操控符。precision对所有输出操作具有持续性的作用,而width()对下一个数值操作起作用。程序员往往希望按某种预定格式输出浮点数时,事情变得非常简单,而又不影响在这个流上随后的输出操作。最基本的想法是定义一个表示格式的类,用另一个类表示一个格式再加一个需要格式化的值,之后让运算符“<<”按照格式向ostream输出该值。例如,

程序员可以通过编写自定义的格式化输出函数,实现将数据按各自需要的格式输出。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈