C++【06】输入和输出流

1.C++的输入和输出

输入和输出流的含义

      以前所用到的输入和输出,都是以终端为对象的,即从键盘输入数据,运行结果输出到显示器屏幕上。
      从操作系统的角度看,每一个与主机相连的输入输出设备都被看作一个文件。
      程序的输入指的是从输入文件将数据传送给程序,程序的输出指的是从程序将数据传送给输出文件。C++的输入与输出包括以下3方面的内容:
(1) 对系统指定的标准设备的输入和输出。即从键盘输入数据,输出到显示器屏幕。称为标准的输入输出,简称标准I/O。
(2) 以外存磁盘文件为对象进行输入和输出,即从磁盘文件输入数据,数据输出到磁盘文件。称为文件的输入输出,简称文件I/O。
(3) 对内存中指定的空间进行输入和输出。通常指定一个字符数组作为存储空间(实际上可以利用该空间存储任何信息)。称为字符串输入输出,简称串I/O。
      C++采取不同的方法来实现以上3种输入输出。
      为了实现数据的有效流动,C++系统提供了庞大的I/O类库,调用不同的类去实现不同的功能。

C++的I/O对C的发展——类型安全和可扩展性

      在C语言中,用printf和scanf进行输入输出,往往不能保证所输入输出的数据是可靠的、安全的。
      在C++的输入输出中,编译系统对数据类型进行严格的检查,凡是类型不正确的数据都不可能通过编译。因此C++的I/O操作是类型安全(type safe)的。
C++通过I/O类库来实现丰富的I/O功能。C++的输入输出优于C语言中的printf和scanf,但是比较复杂。

C++的输入输出流

      C++的输入输出流是指由若干字节组成的字节序列,这些字节中的数据按顺序从一个对象传送到另一对象。
      实际上,在内存中为每一个数据流开辟一个内存缓冲区,用来存放流中的数据。流是与内存缓冲区相对应的,或者说,缓冲区中的数据就是流。
      在C++中,输入输出流被定义为类。C++的I/O库中的类称为流类(stream class)。用流类定义的对象称为流对象。
cout和cin并不是C++语言中提供的语句,它们是iostream类的对象。

(1)iostream类库中有关的类

      C++编译系统提供了用于输入输出的iostream类库。在iostream类库中包含许多用于输入输出的类。常用的见书中表7.1。
      ios是抽象基类,由它派生出istream类和ostream类。istream类支持输入操作,ostream类支持输出操作。 iostream类是从istream类和ostream类通过多重继承而派生的类,iostream类支持输入输出操作。
      C++对文件的输入输出需要用ifstream和ofstream类。ifstream支持对文件的输入操作,ofstream支持对文件的输出操作。类ifstream继承了类istream,类ofstream继承了类ostream,类fstream继承了类iostream。
在这里插入图片描述
(2)与iostream类库有关的头文件
      iostream类库中不同的类的声明被放在不同的头文件中,用户在自己的程序中用#include命令包含了有关的头文件就相当于在本程序中声明了所需要用到的类,常用的有
      iostream包含了对输入输出流进行操作所需的基本信息。
fstream用于用户管理的文件的I/O操作。
strstream用于字符串流I/O。
stdiostream用于混合使用C和C++的I/O机制时。
iomanip在使用格式化I/O时应包含此头文件。

2.标准输出流

标准输出流是流向标准输出设备(显示器)的数据。

cout,cerr和clog流

ostream类定义了3个输出流对象,即cout,cerr,clog。

  1. cout流对象
    cout是console output的缩写,意为在控制台(终端显示器)的输出。
    (1) cout不是C++预定义的关键字,它是ostream流类的对象,在iostream中定义。
    (2) 用“cout<<”输出基本类型的数据时,可以不必考虑数据是什么类型,系统会判断数据的类型,并根据其类型选择调用与之匹配的运算符重载函数。
    (3) cout流在内存中对应开辟了一个缓冲区,用来存放流中的数据,当向cout流插入一个endl时,不论缓冲区是否已满,都立即输出流中所有数据,然后插入一个换行符,并刷新流(清空缓冲区)。
    (4) 在iostream中只对“<<”和“>>”运算符用于标准类型数据的输入输出进行了重载,但未对用户声明的类型数据的输入输出进行重载。
  2. cerr流对象
    cerr流对象是标准错误流。cerr流已被指定为与显示器关联。
    cerr的作用是向标准错误设备(standard error device)输出有关出错信息。
  3. clog流对象
    clog流对象也是标准错误流,它是console log的缩写。它的作用和cerr相同,都是在终端显示器上显示出错信息。区别: cerr是不经过缓冲区,直接向显示器上输出有关信息,而clog中的信息存放在缓冲区中,缓冲区满后或遇endl时向显示器输出。

格式输出

在输出数据时,有时希望数据按指定的格式输出。有两种方法可以达到此目的。一种是使用控制符;另一种是使用流对象的有关成员函数。

  1. 使用控制符控制输出格式
    应当注意,这些控制符是在头文件iomanip中定义的,因而程序中应当包含iomanip。
  2. 用流对象的成员函数控制输出格式
    除了可以用控制符来控制输出格式外,还可以通过调用流对象cout中用于控制输出格式的成员函数来控制输出格式。
    流成员函数setf和控制符setiosflags括号中的参数表示格式状态,它是通过格式标志来指定的。格式标志在类ios中被定义为枚举值。因此在引用这些格式标志时要在前面加上类名ios和域运算符“::”。

3.标准输入流

      标准输入流是从标准输入设备(键盘)流向程序的数据。

cin流

cin是istream类的对象,它从标准输入设备(键盘)获取数据,程序中的变量通过流提取符“>>”从流中提取数据。流提取符“>>”从流中提取数据时通常跳过输入流中的空格、tab键、换行符等空白字符。
注意: 只有在输入完数据再按回车键后,该行数据才被送入键盘缓冲区,形成输入流,提取运算符“>>”才能从中提取数据。

用于字符输入的流成员函数

除了可以用cin输入标准类型的数据外,还可以用istream类流对象的一些成员函数,实现字符的输入。

  1. 用get函数读入一个字符
    流成员函数get有3种形式: 无参数的,有一个参数的,有3个参数的。
    (1) 不带参数的get函数
    其调用形式为
    cin.get()
    用来从指定的输入流中提取一个字符,函数的返回值就是读入的字符。若遇到输入流中的文件结束符,则函数值返回文件结束标志EOF(End Of File) 。
    (2) 有一个参数的get函数
    其调用形式为
    cin.get(ch)
    其作用是从输入流中读取一个字符,赋给字符变量ch。如果读取成功则函数返回非0值(真),如失败(遇文件结束符) 则函数返回0值(假)。
    (3) 有3个参数的get函数
    其调用形式为
    cin.get(字符数组,字符个数n,终止字符)

    cin.get(字符指针,字符个数n,终止字符)
    其作用是从输入流中读取n-1个字符,赋给指定的字符数组(或字符指针指向的数组),如果在读取n-1个字符之前遇到指定的终止字符,则提前结束读取。如果读取成功则函数返回非0值(真),如失败(遇文件结束符) 则函数返回0值(假)。
  2. 用成员函数getline函数读入一行字符
    getline函数的作用是从输入流中读取一行字符,其用法与带3个参数的get函数类似。即
    cin.getline(字符数组(或字符指针),字符个数n,终止标志字符)

4.文件操作与文件流

文件的概念

根据文件中数据的组织形式,可分为ASCII文件和二进制文件。

文件流类与文件流对象

在C++的I/O类库中定义了几种文件类,专门用于对磁盘文件的输入输出操作。
(1) ifstream类,它是从istream类派生的。 用来支持从磁盘文件的输入。
(2) ofstream类,它是从ostream类派生的。 用来支持向磁盘文件的输出。
(3) fstream类,它是从iostream类派生的。 用来支持对磁盘文件的输入输出。
要以磁盘文件为对象进行输入输出,必须定义一个文件流类的对象,通过文件流对象对数据进行操作。

文件的打开和关闭

  1. 打开磁盘文件
    打开文件是指在文件读写之前做必要的准备工作,包括:
    (1) 为文件流对象和指定的磁盘文件建立关联,以便使文件流流向指定的磁盘文件。
    (2) 指定文件的工作方式。
    以上工作可以通过两种不同的方法实现。
    (1) 调用文件流的成员函数open。如
    ofstream outfile;//定义ofstream类(输出文件流类)对象outfile
    outfile.open(″f1.dat″,ios::out); //使文件流与f1.dat文件建立关联
    调用成员函数open的一般形式为
    文件流对象.open(磁盘文件名,输入输出方式);
    磁盘文件名可以包括路径,如″c:\new\f1.dat″,如缺省路径,则默认为当前目录下的文件。
    (2) 在定义文件流对象时指定参数

    ostream outfile(″f1.dat″,ios::out);
    一般多用此形式,比较方便。作用与open函数相同。
    输入输出方式是在ios类中定义的,它们是枚举常量,有多种选择。
  2. 关闭磁盘文件
    在对已打开的磁盘文件的读写操作完成后,应关闭该文件。关闭文件用成员函数close。如
    outfile.close( );//将输出文件流所关联的磁盘文件关闭
    所谓关闭,实际上是解除该磁盘文件与文件流的关联,原来设置的工作方式也失效,这样,就不能再通过文件流对该文件进行输入或输出。

对ASCLL文件的操作

对ASCII文件的读写操作可以用以下两种方法:
(1) 用流插入运算符“<<”和流提取运算符“>>”输入输出标准类型的数据。
(2) 用之前介绍的文件流的put,get,geiline等成员函数进行字符的输入输出。

对二进制文件的操作

      对二进制文件的操作也需要先打开文件,用完后要关闭文件。在打开时要用ios::binary指定为以二进制形式传送和存储。二进制文件除了可以作为输入文件或输出文件外,还可以是既能输入又能输出的文件。这是和ASCII文件不同的地方。
对二进制文件的读写主要用istream类的成员函数read和write来实现。

5.字符串流

      字符串流不是以外存文件为输入输出的对象,而以内存中用户定义的字符数组(字符串)为输入输出的对象。字符串流也称为内存流。
      文件流类有ifstream,ofstream和fstream,而字符串流类有istrstream,ostrstream和strstream。文件流类和字符串流类都是ostream,istream和iostream类的派生类,因此对它们的操作方法是基本相同的。向内存中的一个字符数组写数据就如同向文件写数据一样,但有3点不同:
(1) 输出时数据不是流向外存文件,而是流向内存中的一个存储空间。输入时从内存中的存储空间读取数据。
(2) 字符串流对象关联的不是文件,而是内存中的一个字符数组,因此不需要打开和关闭文件。
(3) 每个文件的最后都有一个文件结束符,表示文件的结束。而字符串流所关联的字符数组中没有相应的结束标志,用户要指定一个特殊字符作为结束符,在向字符数组写入全部数据后要写入此字符。
      字符串流类没有open成员函数,因此要在建立字符串流对象时通过给定参数来确立字符串流与字符数组的关联。
建立字符串流对象的方法如下:

建立输出字符串流对象

ostrstream类提供的构造函数的原型为
ostrstream::ostrstream(char *buffer,int n,int mode=ios::out);
buffer是指向字符数组首元素的指针,n为指定的流缓冲区的大小(一般选与字符数组的大小相同,也可以不同),第3个参数是可选的,默认为ios::out方式。
可以用以下语句建立输出字符串流对象并与字符数组建立关联:
ostrstream strout(ch1,20);
作用是建立输出字符串流对象strout,并使strout与字符数组ch1关联(通过字符串流将数据输出到字符数组ch1),流缓冲区大小为20。

建立输入字符串流对象

istrstream类提供了两个带参的构造函数,原型为
istrstream::istrstream(char *buffer);
istrstream::istrstream(char *buffer,int n);
buffer是指向字符数组首元素的指针,用它来初始化流对象(使流对象与字符数组建立关联)。
可以用以下语句建立输入字符串流对象:
istrstream strin(ch2);
作用是建立输入字符串流对象strin,将字符数组ch2中的全部数据作为输入字符串流的内容。
istrstream strin(ch2,20);
流缓冲区大小为20,因此只将字符数组ch2中的前20个字符作为输入字符串流的内容。

建立输入输出字符串流对象

strstream类提供的构造函数的原型为
strstream::strstream(char *buffer,int n,int mode);
可以用以下语句建立输入输出字符串流对象:
strstream strio(ch3,sizeof(ch3),ios::in|ios::out);
作用是建立输入输出字符串流对象,以字符数组ch3为输入输出对象,流缓冲区大小与数组ch3相同。
以上3个字符串流类是在头文件strstream中定义的,因此程序中在用到istrstream, ostrstream和strstream类时应包含头文件strstream。

猜你喜欢

转载自blog.csdn.net/The_Handsome_Sir/article/details/106849156