输入输出流 学习笔记(一)

1 C++的输入和输出

1.1输入和输出的含义
程序的输入指的是从输入文件将数据传送给程序;
程序的输出指的是从程序将数据传送给输出文件。

C++的输入和输出包括以下三方面的内容:

a)   对系统指定的标准设备的输入和输出,简称标准I/O;
b)   以外磁盘文件为对象进行输入和输出,简称文件I/O;
c)   对内存中的指定的空间进行输入和输出,简称为串I/O。

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

  1. Iostream类库中有关的类
    C++系统提供了用于输入和输出的iostream类库。istream类支持输入操作,而ostream类支持输出操作。
  2. 与iostream类库有关的头文件
    Iostream类库中不同的类的声明被放在不同的头文件中,用户在自己的程序中用#include命令包含了有关的头文件就相当于是在本程序中声明了所需要用到的类。常用的有:
·      iostream包含了对于输入输出流进行操作所需要的基本信息;
·      fstream用于用户管理的文件的I/O操作;
·      strstream用于字符串流I/O操作;
·      stdiostream用于混合使用C和C++的I/O机制时;
·      iomanip在使用格式化I/O的时候应该包含此文件。
  1. 在iostream头文件中定义的流对象
    Iostream.h包含了对于输入输出流进行操作所需要的基本信息。
  2. 在iostream头文件中重载运算符
    在istream类中已将运算符“>>”重载为对于以下标准类型的提取运算符:char, signed char, unsigned char, short, unsigned short, int, unsigned int, long, unsigned long, float, double, lond double, char*, signed char*, unsigned char等。ostream类中,除了以上标准类型外,还增加了一个void类型。

如果想将“<<”和“>>”用于自己声明的类型的数据,就不能够简单的采用包含iostream头文件来解决,需要对“<<”和“>>”进行重载。

2 标准输出流

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

  1. cout流对象
    a) cout是ostream流类的对象,在iostream中定义;
    b) ;
    c) 用“cout<<”输出基本类型的数据时,可以不必考虑数据是什么类型,系统会判断数据的类型,并根据其类型选择调用与之匹配的运算符重载函数;
    d) cout流在内存中开辟了一个缓冲区,用来存放流中的数据,当向cout流插入一个endl时,不论缓冲区是否存满,都立即输出流中所有的数据,然后插入一个换行符,并刷新流(清空缓冲区);
    e) 在iostream中只对“<<”和“>>”运算符用于标准类型数据的输入和输出进行了重载,但未对用户声明的数据类型的输入输出进行重载。
  2. cerr流对象
    cerr与标准输出流cout的作用和用法差不多,但有一点不同:cout流通常是传送到显示器输出,但也可以被重定向输出到磁盘文件,而cerr流中的信息只能够在显示器输出。当调试程序的时候,往往不希望出错的信息被送到其他文件,而要求在显示器及时输出,这时候应该用cerr,cerr流中的信息是用户根据需要指定的。
  3. clog流对象
    clog流对象也是标准错误流,他的作用与cerr相同,区别是:cerr是不经过缓冲区,直接向显示器上输出有关信息,而clog中的信息存放在缓冲区中,缓冲区满后或遇到endl时向显示器输出。

2.2 格式输出
可以使用控制符或使用流对象的有关成员函数来实现格式输出。

  1. 使用控制符控制输出格式
    应当注意,这些控制符是在头文件iomanip中定义的,因而程序中应当包含iomanip。
  2. 用流对象的成员函数来控制输出格式
    在引用格式标志时,需要在前面加上类名ios和域运算符“::”。

2.3 用流成员函数put输出字符
ostream类除了提供用于格式控制的成员函数外,还提供了专用于输出单个字符的成员函数put。如:cout.put(‘a’);

3 标准输入流
3.1 cin流
流提取运算符“<<”从流中提取数据时,通常跳过输入流中的空格,tab键,换行符等空白字符。
注意只有在输入完数据再按回车键后,该行数据才被送入键盘缓冲区,形成输入流,流提取运算符“<<”才能从中提取数据。

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

1)   用get函数读入一个字符
流成员函函数get有3种形式:无参数的,有一个参数,有3个参数。
a)   不带参数的get函数
调用格式为:
 cin.get()
用来从指定的输入流中提取一个字符。
b)   有一个参数的get函数
调用形式为:
cin.get(ch)
其作用是从输入流中读取一个字符,赋值给字符变量ch。
c)   有3个参数的get函数
调用形式为:
cin.get(字符数组,字符个数n,终止字符)
或
cin.get(字符指针,字符个数n,终止字符)
其作用是从输入流中读取n-1个字符,赋值给指定的字符数组(或者是字符指针指向的数组),如果在读取n-1个字符之前遇到指定的终止字符,则提前读取结束。
  1. 用成员函数getline函数读入一行字符
getline函数的作用是从输入流中读取一行字符,其用法与带3个参数的get函数类似,即:
cin.getline(字符数组(或字符指针),字符个数n,终止标志字符)

3.3 istream类的其他成员函数

  1. eof函数
从输入流读取数据,如果到达文件末尾(遇见文件结束符号),eof函数值为非零值(表示真),否则为0(假)。
  1. peek函数
peek函数的作用是观测下一个字符,调用形式为:
c=cin.peek();

函数的返回值是指针指向的当前字符,但它只是观测,指针仍然停留在当前位置,并不后移,如果要访问的字符是文件结束符,则函数值是EOF(-1)。
3) putbak函数

调用形式为:
putback(ch);

其作用是将前面用get或者getline函数从输入流中读取的字符ch返回到输入流,插入到当前指针的位置,以便后面读取。
4) ignore函数
调用形式为:

cin.ignore(n,终止字符)
函数的作用是跳过输入流中的n个字符,或者在遇到指定的终止字符时提前结束(此时,跳过包括终止字符在内的若干字符)。

例如:ignore(5,’A’)//跳过输入流中的5个字符,遇到’A’后就不再跳了;
也可以不带参数或者是只带一个参数,如:
ignore()(n默认为1,终止字符默认为EOF)
相当于
ignore(1,EOF)

4 文件操作与文件流
4.1 文件的概念
文件一般是指存储在外部介质上数据的集合。外存文件包括磁盘文件,光盘文件和U盘文件。
对于用户来说,常用到的文件有两大类,一类是程序文件,另外一类则是数据文件。
4.2 文件流类与文件流对象
C++的I/O类库中定义了几种文件类,专门用于对于磁盘文件进行输入和输出操作,除了已经介绍过的istream,ostream和iostream,还有3个用于文件操作的文件类:

a)   ifstream类,从istream类派生,用来支持从磁盘文件的输入;
b)   ofstream类,它是从ostream类派生的,用来支持向磁盘文件的输出;
c)   fstream类,它是从iostream类派生的,用来支持对于磁盘文件的输入和输出。

要以磁盘文件为对象进行输入和输出,必须定义一个文件流类的对象,通过文件流对象将数据从内存中输出到磁盘文件,或者通过文件流对象从磁盘文件将数据输入到内存。

例如,可以用下面的方法建立一个输出文件流对象:

ofstream outfile;

4.3 文件的打开与关闭

  1. 打开磁盘文件
    打开文件是指在文件的读写之前做必要的准备工作,包括:
    a) 为文件流对象和指定的磁盘文件建立关联,以便使文件流流向指定的磁盘文件;
    b) 指定文件的工作方式。
    以上的工作可以通过两种不同的方法实现:
    a) 调用文件流的成员函数open
    调用成员函数open的一般形式为:
    文件流对象.open(磁盘文件名,输入输出方式);
    磁盘文件名可以包括路径,如果缺省路径,则默认为当前目录下的文件。
    例如:
    ofstream outfile; //定义ofstream类的对象outfile
    outfile.open(“f1.dat”,ios::out); //使文件流与f1.dat文件建立关联
    b) 在定义文件流对象时指定参数
    在声明文件流类时定义了带参数的构造函数,其中包含了打开磁盘文件的功能,因此,可以在定义文件流对象的时候指定参数,调用文件流类的构造函数来实现打开文件的功能。如:
    ostream outfile(“f1.dat”,ios::out);
    一般多采用这种形式,比较方便,作用与open函数相同。
    输入输出方式是在ios类中定义的,它们是枚举常量,有多种选择。

  2. 关闭磁盘文件
    关闭文件用成员函数close,如:
    outfile.close();

4.4 对ASCII文件的操作
如果文件中的每一个字节中均以ASCII代码形式存放数据,即一个字节存放一个字符,这个文件就是ASCII文件(或者是字符文件)。
对于ASCII文件的读写操作可以用以下两种方法:
a) 用流插入运算符“<<”和流提取运算符“>>”输入输出标准类型的数据;
b) 可以用文件流的put,get,getline等成员函数进行字符的输入和输出。

4.5 对二进制文件的操作

对于二进制文件的操作也需要先打开文件,用完之后再关闭文件,在打开的时候,要用ios::binary指定为二进制形式传送和存储。二进制文件除了可以作为输入文件或者输出文件之外,还可以是既能够输入也能够输出的文件,这是和ASCII文件不同的地方。

  1. 用成员函数read和write读写二进制文件
    对于二进制文件的读写主要是用istream类的成员函数read和write来实现。这两个成员函数的原型为:
istream & read(char *buffer, int len);
ostream & write(const char* buffer, int len);

字符指针指buffer向内存中的一段存储空间,len是读写的字节数。

  1. 与文件指针有关的流成员函数
    在磁盘文件中有一个文件指针,用来指明当前应该进行读写的位置。对于二进制文件,允许对于指针进行控制,使它按照用户的意图移动到所需要的位置,以便在该位置上进行读写。
    文件流提供的一些关于文件指针的成员函数一般具有以下特点:
    a) 这些函数名的第一个字母或者是最后一个字母不是g就是p。
    b) 函数参数中的“文件中的位置”和“位移量”已被指定为long型整数,以字节为单位。“参照位置”可以是下列三者之一:
·      ios::beg文件开头(beg是begin的缩写),这是默认值;
·      ios::cur指针当前的位置(cur是current的缩写);
·      ios::end文件末尾。

它们是在ios中定义的枚举常量。
3) 随机的访问二进制数据文件
不能够用ifstream和ofstream类定义输入输出的二进制文件流对象,而是应该用fstream类。

5 字符串流
文件流,是以外存文件作为输入输出对象的数据流;

字符串流,是以内存中用户定义的字符数组(字符串)为输入输出的对象,即将数据输出到内存中的字符数组,或者是从字符数组(字符串)将数据读入。字符串流也称之为内存流。

文件流类有ifstream,ofstream和fstream,而字符串流类有istrstream,ostrstream, strstream。文件流类和字符串流类都是istream,ostream和iostream类的派生类,因此对于它们的操作方法基本是相同的,除以下3点不同外:

a)   输出时数据不是流向外存文件,而是流向内存中的一个存储空间。输入时从内存中的存储空间读取数据;
b)   字符串流对象关联的不是文件,而是内存中的一个字符数组,因此不需要打开与关闭操作;
c)   每个文件的最后都有一个文件结束符,表示文件的结束;而字符串流所关联的字符数组中没有相应的结束标志,用户需要指定一个特殊的字符作为结束符,在向字符数组写入全部数据之后,要写入此字符。
  1. 建立输出字符串流对象
    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.

  1. 建立输入字符串流对象
    istrstream类提供了两个带参数的构造函数,原型为:
istrstream::istrstream(char *buffer);
istrstream::istrstream(char *buffer, int n);

buffer是指向字符数组首元素的指针,用它来初始化流对象(使得流对象和字符数组建立关联),可以用以下语句建立输入字符串流对象:

istrstream  strin(ch2);

作用是建立输入字符串流对象strin,将字符数组ch2中的全部数据作为输入字符串流的内容。

istrstream  strin(ch2, 20);

流缓冲区大小为20,因此只将字符数组ch2中的前20个字符作为输入字符串流的内容。

  1. 建立输入输出字符串流对象
    strstream类提供的构造函数的原型为
strstream::strstream(char *buffer, int n, int mode);

例如,可以通过以下语句建立输入输出字符串流对象:

strstream strio(ch3, sizeof(ch3), ios::in|ios::out);

作用是建立输入输出字符串流对象,以字符数组ch3为输入输出对象,缓冲区大小与数组ch3相同。

Note:
以上3个字符串流类是在头文件strstream中定义的,因此程序中再用到istrstream,ostrstream和strstream 类的时候,应该要包含头文件strstream(在Gcc中,用头文件strstream)。

猜你喜欢

转载自blog.csdn.net/weixin_43667308/article/details/86633777