C++流类库与C的I/O操作优势比较,文件与流

1、C++流类库和C语言的I/O操作相比:

(1) 简明与可读性

从直观上来看,C++的这种改变使得I/O 语句更为简明,增加了可读性。用I/O运算符(提取运算符>>和插入运算符<<)代替不同的输入输出函数名(如printf,scanf 等)是一个大的改进。如:

printf("n=%d,a=%f\n",n,a);

cout<<"n="<<n<<",a="<<a<<endl;

(2) 类型安全(type safe)

所谓类型安全,是指在进行I/O 操作时不应对于参加输入输出的数据在类型上发生不应有的变化。如:

show(int color,float size){

cout<<"color="<<color<<",size="<<size<<endl;

}

在这个函数的调用过程中,系统(编译器)将自动按参数的类型定义检查实参的表达式,显示的结果中,第一个自然是整数值,第二个size 必然是浮点类型值。

如果采用printf()函数,由于其参数中的数据类型必须由程序员以参数格式%d,%f,%c,%s 的形式给出,同样实现上述函数show(),就可能产生编译器无法解决的问题:

show(int color,float size){

printf("color=%f,size=%d\n",color,size);

}

程序员在确认输出数据类型时发生错误是可能的,这时输出数据的类型:color 是int 型,size 是float 型,与printf()中给出的参数格式符%f 对应color,%d 对应于size,两者发生了矛盾。因此说,它是类型不安全的。而C++的I/O系统不会出现这种情形。

(3) 易于扩充

在C++语言所附的I/O 系统,在其流类的定义中,把原来C++语言中的左、右移位运算符<<和>>,通过运算符重载的方法,定义为插入(输出)和提取(输入)运算符。这就为输入输出功能对于各种用户定义的类型数据的扩充,创造了方便的条件。而在stdio.h 文件中说明的printf()函数却很难做到这一点。例如在C++语言提供的I/O 系统中,它是把运算符‘<<’的重载函数作为输出流类ostream 的成员函数来定义的,分别对字符串char,short,int,long,float,double,const void *(指针)等类型作了说明。在此基础上,用户不难对于新的类型数据的输出来重载运算符‘<<’。它可以作为用户定义的类型(例如类complex)的友元函数来定义:

friend ostream &operator<<(ostream &s,complex &c){

s<<'('<<c.re<<','<<c.im<<')';return s;

}

2、文件和流

    文件分为文本文件和二进制文件,前者以字节(byte)为单位,每字节对应一ASCII 码,表示一个字符,故又称字符文件。二进制文件以字位(bit)为单位,实际上是由0 和1 组成的序列。例如整数1245 以文本形式存储占用四个字节,以二进制形式存储则可能只占用两个字节(16 bits)。

在程序中,文件的概念不单是狭义地指硬盘上的文件,所有的有输入输出功能的设备,例如键盘,控制台,显示器,打印机都被视为文件。这就是广义的文件的概念。就输入输出操作来说,这些外设和硬盘上的文件是一致的,对于程序员来说文件只与信息的输入输出相关,而且这种输入输出是串行序列形式的。于是,人们把文件的概念抽象为“流”(stream)。流是程序设计对I/O 系统中文件的抽象。一个输入文件,它可能是一个只读磁盘文件,也可能是键盘,一律把它视为流的“源”。而一个输出文件则称为流的“汇”。

C++的I/O 系统,定义了一系列由某种继承派生关系的流类,并为这些抽象的流类定义一系列的I/O 操作函数,当需要进行实际的I/O 操作时,只需创建这些类的对象(称为流),并令其与相应的物理文件(硬盘文件名或外设名)相联系。因此,文件可以说是个物理概念,而流则是一个逻辑概念。I/O 操作是针对抽象的流来定义的,对文件的I/O 操作,其前提是把该文件与一个(对象)流联系起来,这是C++的I/O 系统的基本原理。

在内存中开辟一片区域作为输入输出操作的缓冲区,可以提高运行效率,因此I/O 操作可以区分缓冲I/O 和非缓冲I/O。

严格地说,C++的I/O 系统并不是C++语言的一部分,它是系统为用户提供专用于I/O 的标准类(及函数,对象)等。作为基本类的主要几个类在头文件iostream.h 中被说明。下面将其中几个主要类的内容作一简介。

· ios 类:在其中以枚举定义方式给出一系列与I/O 有关的状态标志,工作方式等常量,定义了一系列涉及输入输出格式的成员函数(包括设置域宽,数据精度等),它的一个数据成员是流的缓冲区指针。同时,类ios 作为蓄积类派生了输入流类istream 和输出流类ostream。

· streambuf 类,负责管理流的缓冲区。包括负责设置缓冲区和在缓冲区与输入流和输出流之间存取字符的操作的成员函数。

· istream 类和ostream 类除继承了类ios 的成员之外,主要为C++的系统数据类型分别对于运算符‘>>’和‘<<’进行重载。

· iostream 类以istream 和ostream 为基类,它同时继承二者,以便创建可以同时进行I/O 操作的流。

· istream-withassign 类是istream 的派生类,主要增加了输入流(对象)之间的赋值(‘=’)运算。

· ostream-withassign 类是ostream 的派生类,主要增加了输出流(对象)之间的赋值(‘=’)运算。

· iostream-withassign 类是iostream 的派生类。

streambnf 类与ios 类之间没有继承关系,当I/O操作需要使用I/O 缓冲区时,可以创建缓冲区对象,通过流的缓冲区指针,来完成有关缓冲区的操作。 大多数I/O 操作的函数包括在ios 类和istream 类,ostream 类,iostream 类中。名字带有“withassign”的三个类,实际上是补充了流对象的赋值操作。由此也可以看到,具有层次关系的类说明的灵活性。在头文件iostream.h 中,除了类的定义之外,还包括四个对象的说明,它们被称为标准流,或预定义流。

· cin 是类istream-withassign 的对象,为标准输入流,在不作其它说明条件下,与标准输入设备(一般指键盘)相关联。

· cout 是类ostream-withassign 的对象,为标准输出流,在不作其它说明条件下,与标准输出设备(显示器)相关联。

· cerr,clog 也是类ostream-withassign 的对象,与标准(错误)输出设备(显示器)相关联,前者为非缓冲方式,后者为缓冲方式。一般说来,未作说明的流是缓冲的。若令cerr 为非缓冲的流,可以保证出现错误后立即把出错信息在显示器上输出。

附:istrstream 类

1、功能简介:

istrstream 类是从 istream 类派生的,它是用来将文本项转换为变量所需要的内部格式。

istrstream 类的构造函数有两个:

istrstream::istrstream(char *s);

istrstream::istrstream(char *s,int n);

参数说明:

⒈第一个参数 s 是一个字符指针或字符数组,使用该串来初始化要创建的流对象。

⒉ n 表示使用前 n 个字符来构造流对象。

2、用法心得:

istrstream 用来构造一个用于输入的字符串流。可以像cin一样用 。在istrstream流中,以空格为分割符。

3.具体例子:

例一:先将字符串的值初始化到流对象ins中,然后分别赋给三个变量中。它们以空格为分割符。

#include <iostream>

#include <strstream>

using namespace std;

int main()

{

char s[ ] = "Uno 2 3.00";

istrstream ins(s); 

int i;

char str[80];

float f;  

ins >> str;  //str's value is Uno

ins >> i; //i's value is 2

cout << str << " " << i << endl;  

ins >> f; //f's value is 3

cout << f << '\n';

return 0;

}

发布了208 篇原创文章 · 获赞 30 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/hopegrace/article/details/104219516