C++的那些事:流与IO类
作者:RonnyYoung 发布时间:[ 2016/10/28 10:25:46 ] 推荐标签:C++ IO 流
1、流的概念
"流"是"流动",是物质从一处向另一处流动的过程,比如我们能感知到的水流。C++的流是指信息从外部输入设备(如键盘和磁盘)向计算机内部(即内存)输入和从内存向外部输出设备(如显示器和磁盘)输出的过程,这种输入输出过程被形象地比喻为"流"。
为了实现信息的内外流动,C++系统定义了I/O类库,其中的每一个类都称作相应的流或流类,用以完成某一方面的功能。根据一个流类定义的对象也时常被称为流。
通常标准输入或标准输出设备显示器称为标准流;外存磁盘上文件的输入输出称为文件流;对于内存中指定的字符串存储空间称为字符串流。
那么流的内容通常是什么呢?
流里的基本单位是字节,所以又称为字节流。字节流可以是ASCII字符、二进制数据、图形图像、音频视频等信息。文件和字符串也可以看成是有序的字节流,又称为文件流和字符串流。
2、IO类
C++的IO类库属于STL的一部分,在STL中定义了一个庞大的类库,它们的继承关系为下图:
管理标准的输入/输出流的类为:istream(输入)、ostream(输出)、iostream(输入输出),其中istream和ostream直接从ios中继承,iostream多重继承了istream和otream。而cin是STL中定位的一个用于输入的istream对象,cout、cerr、clog是三个用于输出的ostream对象。其中cout对象也被称为标准输出,用于正常的输出,cerr用来输出警告和错误信息,因为被称为标准错误,而clog用来输出程序运行时的一般性信息。cerr和clog之间的不同之处在于cerr是不经过缓冲区直接向显示器输出有关信息,而clog则是先把信息放在缓冲区,缓冲区满后或遇上endl时向显示器输出。
管理文件流的类为:ifstream(文件输入)、ofstream(文件输出)和fstream(文件的输入/输出)。其中ifstream是从istream中继承的类,ofstream是从ostream中继承的类,fstream是从iostream继承的类。
管理字符串流的类为:istringstream(字符串输入)、ostringstream(字符串输出)和stringstream(字符串的输入/输出)。其中istringstream是从istream中继承的类,ostringstream是从ostream中继承的类,stringstream是从iostream继承的类。
3,<<和>>操作符 3.1 <<的用法
在istream输入流类中定义有对右移操作符>>重载的一组公用成员函数,函数的具体声明格式为:
istream& operator>> (istream& is, char& c);
istream& operator>> (istream& is, signed char& c);
istream& operator>> (istream& is, unsigned char& c);
istream& operator>> (istream& is, char* s);
istream& operator>> (istream& is, signed char* s);
istream& operator>> (istream& is, unsigned char* s);
由于右移操作符重载用于给变量输入数据的操作,所以又称为提取操作符,即从流中提取出数据赋给变量。
当系统执行cin>>variable操作时,将根据实参x的类型调用相应的提取操作符重载函数,把variable引用传送给对应的形参,接着从键盘的输入中读入一个值并赋给variable后,返回cin流,以便继续使用提取操作符为下一个变量输入数据。
当从键盘上输入数据时,只有当输入完数据并按下回车键后,系统才把该行数据存入到键盘缓冲区,供cin流顺序读取给变量。还有,从键盘上输入的每个数据之间必须用空格或回车符分开,因为cin为一个变量读入数据时是以空格或回车符作为其结束标志的。
当cin>>str_ptr操作中的str_ptr为字符指针类型时,则要求从键盘的输入中读取一个字符串,并把它赋值给str_ptr所指向的存储空间中,若str_ptr没有事先指向一个允许写入信息的存储空间,则无法完成输入操作。另外从键盘上输入的字符串,其两边不能带有双引号定界符,若带有只作为双引号字符看待。对于输入的字符也是如此,不能带有单引号定界符。
3.2 >>的用法
在ostream输出流类中定义有对左移操作符<<重载的一组公用成员函数,函数的具体声明格式为:
istream& operator>> (bool& val);
istream& operator>> (short& val);
istream& operator>> (unsigned short& val);
istream& operator>> (int& val);
istream& operator>> (unsigned int& val);
istream& operator>> (long& val);
istream& operator>> (unsigned long& val);
istream& operator>> (long long& val);
istream& operator>> (unsigned long long& val);
istream& operator>> (float& val);
istream& operator>> (double& val);
istream& operator>> (long double& val);
istream& operator>> (void*& val);
除了与在istream流类中声明右移操作符重载函数给出的所有内置类型以外,还增加一个void* 类型,用于输出任何指针(但不能是字符指针,因为它将被作为字符串处理,即输出所指向存储空间中保存的一个字符串)的值。
由于左移操作符重载用于向流中输出表达式的值,所以又称为插入操作符。如当输出流是cout时,则把表达式的值插入到显示器上,即输出到显示器显示出来。
当系统执行cout<<variable操作时,首先根据x值的类型调用相应的插入操作符重载函数,把variable的值按值传送给对应的形参,接着执行函数体,把variable的值(亦即形参的值)输出到显示器屏幕上,从当前屏幕光标位置起显示出来,然后返回cout流,以便继续使用插入操作符输出下一个表达式的值。
4,IO条件状态 4.1 查询流的状态
IO操作都有可能发生错误,一些错误是可恢复的,而其他错误发生在系统深处,已经超出了应用程序可以修正的范围。
IO类定义了一些函数和标志,可以帮助我们访问和操纵流的条件状态。
首先表示一个流当前的状态的变量的类型为strm::iostate,其中strm是一种流类型,可以是iostream、fstream等。比如,我们定义一个标准IO流状态:
iostream::iostate strm_state=iostream::goodbit;
IO库存定义了4个iostate类型的contexpr值,表示特定的位模式。这些值用来表示特定类型的IO条件,可以与位运算一起使用来一次性检测或设置多个标志位。
1)strm::badbit用来指定流已崩溃。它表示系统级的错误,如不可恢复的读写错误。通常情况下,一旦badbit被置位,流无法再使用了。
2)strm::failbit用来指出一个IO操作失败了。
3)strm::eofbit用来指出流达了文件的结束。
在发生可恢复错误后,failbit被置位,如期望读取数值却读出一个字符错误。这种问题通常可以修正,流还可以继续使用。如果到达文件结束位置,eofbit和failbit都会被置位。
4)strm::goodbit用来指出流未处于错误状态。此值保证为零。
goodbit的值为0,表示流未发生错误。如果badbit、failbit和eofbit任一个置位,则检测流状态的条件会失败。
标准库还定义了一组函数来查询这些标志位的状态,假如s是一个流,那么:
s.eof() // 若流s的eofbit置位,则返回true
s.fail() // 若流s的failbit或badbit置位,则返回true
s.bad() // 若流s的badbit被置位,则返回true
s.good() // 若流s处于有效状态,则返回true
在实际我们在循环中判断流的状态是否有效时,都直接使用流对象本身,比如:while(cin>>variable){cout<<variable},在实际中都转换为了while((cin>>variable).good()){cout<<variable}。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11