1、C+程序设计第第9 9章章 输入输出流输入输出流第第9章章输入输出流输入输出流 本章学习要点本章学习要点完成程序的基本功能需要有初始数据的输入完成程序的基本功能需要有初始数据的输入和运行结果的输出和运行结果的输出.本章重点介绍本章重点介绍C+输入输入/输出流库、预定义类输出流库、预定义类型数据的输入和输出、格式控制、自定义类型数据的输入和输出、格式控制、自定义类型数据的输入和输出以及文件的输入和输出型数据的输入和输出以及文件的输入和输出等内容。等内容。v9.1 C+的输入和输出概述的输入和输出概述v9.2 C+的标准输入的标准输入/输出流输出流v9.3 输入运算符和输出运算符及其重输入运算符和
2、输出运算符及其重载载v9.4 C+格式输入和输出格式输入和输出v9.5 文件操作与文件流文件操作与文件流v9.6 学生信息管理系统中的文件操作学生信息管理系统中的文件操作 第第9章输入输出流章输入输出流9.1 C+的输入和输出概述的输入和输出概述1iostream类库中有关的类类库中有关的类C+除保留除保留C语言的输入输出系统之外,还利用继承的机语言的输入输出系统之外,还利用继承的机制创建出一套自己的方便、一致、安全、可扩充的输入制创建出一套自己的方便、一致、安全、可扩充的输入输出系统,这套输入输出系统就是输出系统,这套输入输出系统就是C+的输入的输入/输出输出(I/O)流库。)流库。vC+自
3、有的输入输出通过编译系统对数据类型进行严格自有的输入输出通过编译系统对数据类型进行严格的检查,凡是类型不正确的数据都不可能通过编译。而的检查,凡是类型不正确的数据都不可能通过编译。而且且C+的的I/O操作是可扩展的,不仅可以用来输入输出操作是可扩展的,不仅可以用来输入输出标准类型的数据,也可以用于用户自定义类型的数据。标准类型的数据,也可以用于用户自定义类型的数据。C+对标准类型的数据和对用户自定义类型的数据的输对标准类型的数据和对用户自定义类型的数据的输入入/输出,采用同样的方法处理。输出,采用同样的方法处理。C+通过通过I/O流类库来流类库来实现丰富的实现丰富的I/O功能。功能。vC+的输
4、入输出优于的输入输出优于C语言中的语言中的printf()和和scanf(),但是,但是相对来说比较复杂,要掌握许多细节。相对来说比较复杂,要掌握许多细节。9.2 C+的标准输入的标准输入/输出流输出流vC+的输入输出流是指由若干字节组的输入输出流是指由若干字节组成的字节序列,这些字节中的数据按成的字节序列,这些字节中的数据按顺序从一个对象传送到另一对象。在顺序从一个对象传送到另一对象。在输入操作时,字节流从输入设备输入操作时,字节流从输入设备(如键如键盘、磁盘盘、磁盘)流向内存,在输出操作时,流向内存,在输出操作时,字节流从内存流向输出设备字节流从内存流向输出设备(如屏幕、如屏幕、打印机、磁
5、盘等打印机、磁盘等)。流中的内容可以是。流中的内容可以是ASCII字符、二进制形式的数据、图形字符、二进制形式的数据、图形图像、数字音频视频或其他形式的信图像、数字音频视频或其他形式的信息。息。vC+的的I/O流库中的类称为流类。用流流库中的类称为流类。用流类定义的对象称为流对象。前面曾提类定义的对象称为流对象。前面曾提到:到:cout和和cin并不是并不是C+语言中提供语言中提供的语句,它们是的语句,它们是I/O流类的对象。在未流类的对象。在未学习类和对象时,在不致引起误解的学习类和对象时,在不致引起误解的前提下,为叙述方便,把它们称为前提下,为叙述方便,把它们称为cout语句和语句和cin
6、语句。在学习了类和对语句。在学习了类和对象后,我们对象后,我们对C+的输入输出应当有的输入输出应当有更深刻的认识。更深刻的认识。v9.2.1 iostream类库中有关的类及其类库中有关的类及其定义的流对象定义的流对象C+编译系统提供了用于输入输出的编译系统提供了用于输入输出的iostream类库。在类库。在iostream类库中包类库中包含许多用于输入输出的类。这些类的含许多用于输入输出的类。这些类的继承层次结构如课本继承层次结构如课本291页图页图9-1所示。所示。为了实现为了实现C+对文件的操作,对文件的操作,C+的的iostream类库中派生定义了用于文件操作的类,它们分别类库中派生定
7、义了用于文件操作的类,它们分别是如下几个类:是如下几个类:vfstreambase类:这是一个公共基类,文件操作类:这是一个公共基类,文件操作中不直接使用这个类。中不直接使用这个类。vifstream类:派生自类:派生自fstreambase类和类和istream类,类,负责对文件进行提取操作。负责对文件进行提取操作。vofstream类:派生自类:派生自fstreambase类和类和ostream类,负责对文件进行插入操作。类,负责对文件进行插入操作。vfstream类:派生自类:派生自fstreambase类和类和iostream类,负责对文件进行插入和提取操作。类,负责对文件进行插入和提
8、取操作。iostream类库中不同的类的声明被放在不同的头文类库中不同的类的声明被放在不同的头文件中,见课本件中,见课本292页表页表9-1。用户在程序中用。用户在程序中用#include命令包含了有关的头文件就相当于在本命令包含了有关的头文件就相当于在本程序中声明了所需要用到的类。程序中声明了所需要用到的类。我们编程时常用的头文件有:我们编程时常用的头文件有:viostream:包含了对输入输出流进行操作所需的:包含了对输入输出流进行操作所需的基本信息。基本信息。vfstream:用于用户管理的文件的:用于用户管理的文件的I/O操作。操作。vstrstream:用于字符串的:用于字符串的I/
9、O。vstdiostream:用于混合使用:用于混合使用C和和C+的的I/O机制机制时。时。viomanip:用于格式化:用于格式化I/O时。时。2在在iostream头文件中定义的流对象头文件中定义的流对象在在iostream头文件中定义的类有:头文件中定义的类有:ios,istream,ostream,iostream,istream _withassign,ostream_withassign,iostream_withassign等。等。iostream头文件包含了对输入输出流进行操作所需的基本信头文件包含了对输入输出流进行操作所需的基本信息。因此大多数息。因此大多数C+程序都包括程序
10、都包括iostream头文件。在头文件。在iostream头文件中不仅定义了有关的类,还定义了头文件中不仅定义了有关的类,还定义了4种流种流对象,供用户使用,它们是:对象,供用户使用,它们是:v cin:是:是istream的派生类的派生类istream_withassign的对象,的对象,它是从标准输入设备它是从标准输入设备(键盘键盘)输入到内存的数据流,称为输入到内存的数据流,称为cin流或标准输入流。流或标准输入流。v cout:是:是ostream的派生类的派生类ostream_withassign的对象,的对象,它是从内存输入到标准输出设备它是从内存输入到标准输出设备(显示器显示器)
11、的数据流,称为的数据流,称为cout流或标准输出流。流或标准输出流。v cerr和和clog:作用相似,均为向输出设备:作用相似,均为向输出设备(显示器显示器)输出出输出出错信息。它们的区别是错信息。它们的区别是cerr提供不带缓冲区的输出,提供不带缓冲区的输出,clog提供带缓冲区的输出。提供带缓冲区的输出。v 从键盘输入时用从键盘输入时用cin流,向显示器输出时用流,向显示器输出时用cout流。向显流。向显示器输出出错信息时用示器输出出错信息时用cerr或或clog流。流。9.2.2 C+的标准输出流的标准输出流标准输出流是流向标准输出设备标准输出流是流向标准输出设备(显示器显示器)的数据
12、。的数据。ostream类类定义了定义了3个输出流对象,即个输出流对象,即cout,cerr,clog。v 1cout,cerr和和clog流流v(1)cout流对象流对象v cout必须和运算符必须和运算符一起使用。用一起使用。用cout进行输出的一般形式进行输出的一般形式为:为:v cout输出项输出项1输出项输出项2.;v 它的功能是将输出项它的功能是将输出项1,输出项,输出项2,.插入到输出流插入到输出流cout中,中,然后由然后由C+系统将系统将cout中的内容输出到显示屏幕上。中的内容输出到显示屏幕上。v 在在C+的头文件的头文件iostream中,定义了一个代表回车换行的控中,定
13、义了一个代表回车换行的控制符制符endl,其作用与,其作用与“n”相同。如下列三个输出语句是等价相同。如下列三个输出语句是等价的:的:coutC+Programn;v coutC+Program n;v coutC+Programendl;而且需要注意的是:而且需要注意的是:v 系统已经对系统已经对“”运算符作了重载函数,因此运算符作了重载函数,因此用用“cout”输出基本类型的数据时,可以不必输出基本类型的数据时,可以不必考虑数据是什么类型。考虑数据是什么类型。v 在在iostream头文件中只对头文件中只对“”运算运算符用于标准类型数据的输入输出进行了重载,但符用于标准类型数据的输入输出进
14、行了重载,但未对用户自定义类型数据的输入输出进行重载。未对用户自定义类型数据的输入输出进行重载。v 在用在用cout进行输出时,每输出一项都要用一个进行输出时,每输出一项都要用一个“”运算符。例如:输出语句:运算符。例如:输出语句:couta=a,b=bendl;不能写成:不能写成:couta=,a,b=,b表达式表达式1表达式表达式2.在上式中,流提取运算符在上式中,流提取运算符“”可以连续写多可以连续写多个,每个后面跟一个表达式,表达式通常个,每个后面跟一个表达式,表达式通常是获得输入值的变量或对象。例题见课本是获得输入值的变量或对象。例题见课本296页页【例例9-3】。v2用成员函数用成
15、员函数get()获取一个字符获取一个字符除了可以用除了可以用cin输入标准类型的数据外,还可以用输入标准类型的数据外,还可以用istream类的成员函数类的成员函数get()从输入流中获取一个从输入流中获取一个字符,并把它放置到变量中。该函数的使用格式字符,并把它放置到变量中。该函数的使用格式有有2种形式:无参数的,有一个参数的。种形式:无参数的,有一个参数的。(1)无参数的)无参数的get()函数函数其调用形式为:其调用形式为:cin.get()其作用是从指定的输入流中提取一个字符,函数的其作用是从指定的输入流中提取一个字符,函数的返回值就是读入的字符。若遇到输入流中的文件返回值就是读入的字
16、符。若遇到输入流中的文件结束符,则函数值返回文件结束标志结束符,则函数值返回文件结束标志EOF(一般情一般情况下认为是况下认为是-1),例题见课本,例题见课本297页页【例例9-4】:v(2)有一个参数的)有一个参数的get()函数函数其调用形式为:其调用形式为:cin.get(char&ch)其作用是从输入流中读取一个字符,赋其作用是从输入流中读取一个字符,赋给字符变量给字符变量ch。如果读取成功则函数。如果读取成功则函数返回非返回非0值值(真真),如失败,如失败(遇文件结束符遇文件结束符)则函数返回则函数返回0值值(假假)。【例例9-4】可以改可以改写为课本写为课本298页的页的【例例9-
17、5】。v 使用使用get()函数还可以输入一行字符。函数还可以输入一行字符。其调用形式为:其调用形式为:cin.get(char*buf,int Limit,Deline=n);这里,这里,*buf可以是一个字符数组或一个字符指针。可以是一个字符数组或一个字符指针。Limit是一个是一个int型数,用来限制从输入流中读取到型数,用来限制从输入流中读取到buf字符数组中的字符个数,最多只能读字符数组中的字符个数,最多只能读Limit-1个,因为个,因为要留出最后一个位置存放结束符。要留出最后一个位置存放结束符。Deline是读取字符是读取字符时指定的结束符,其默认值为时指定的结束符,其默认值为“
18、n”,终止字符也可以终止字符也可以用其他字符,如用其他字符,如cin.get(ch,10,x)。该函数的作用是从输入流中读取该函数的作用是从输入流中读取Limit-1个字符,赋个字符,赋给指定的字符数组给指定的字符数组(或字符指针指向的数组或字符指针指向的数组),如果在,如果在读取读取Limit-1个字符之前遇到指定的终止字符,则提前个字符之前遇到指定的终止字符,则提前结束读取。如果读取成功则函数返回非结束读取。如果读取成功则函数返回非0值值(真真),如失,如失败败(遇文件结束符遇文件结束符)则函数返回则函数返回0值值(假假)。再将。再将【例例9-5】改写例题见课本改写例题见课本299页:页:
19、v 3用成员函数用成员函数getline()函数读入一函数读入一行字符行字符getline()函数的作用是从输入流中读函数的作用是从输入流中读取一行字符,其用法与上面讲述的利用取一行字符,其用法与上面讲述的利用get()函数输入一行字符的功能类似。即函数输入一行字符的功能类似。即cin.getline(char*buf,int Limit,Deline=n);v 4用成员函数用成员函数read()读取一串字符读取一串字符使用成员函数使用成员函数read()可以从输入流中读取可以从输入流中读取指定数目的字符并将它们存放在指定的数组指定数目的字符并将它们存放在指定的数组中。该函数使用格式如下:中。
20、该函数使用格式如下:cin.read(char*buf,int size);其中,其中,buf是用来存放读取来的字符的字是用来存放读取来的字符的字符指针或者是字符数组,符指针或者是字符数组,size是一个是一个int型数,型数,用来指定从输入流中读取字符的个数。课本用来指定从输入流中读取字符的个数。课本300页页【例例9-6】利用利用read()函数读入字符串,函数读入字符串,并输出。并输出。v 5istream类的其他成员函数类的其他成员函数除了以上介绍的用于读取数据的成员函数外,除了以上介绍的用于读取数据的成员函数外,istream类还有其他在输入数据时用得着的一些成类还有其他在输入数据时
21、用得着的一些成员函数。常用的有以下几种:员函数。常用的有以下几种:(1)eof()函数函数eof是是end of file的缩写,表示的缩写,表示“文件结束文件结束”。从输入流读取数据,如果到达文件末尾(遇文件结从输入流读取数据,如果到达文件末尾(遇文件结束符),束符),eof函数值为非零值(表示真),否则为函数值为非零值(表示真),否则为0(假)。其调用格式为:(假)。其调用格式为:cin.eof();课本课本301页页【例例9-7】逐个读入一行字符,将其逐个读入一行字符,将其中的非空格字符输出。中的非空格字符输出。v(2)peek()函数函数peek()函数的作用是从输入流中返回函数的作用
22、是从输入流中返回下一个字符,但它只是观测,指针仍停下一个字符,但它只是观测,指针仍停留在当前位置,遇到流结束标志时返回留在当前位置,遇到流结束标志时返回EOF。其调用形式为:。其调用形式为:c=cin.peek();课本课本301页页【例例9-8】编制程序,检测编制程序,检测字符字符1后面是字符后面是字符2的连续字符组的个数。的连续字符组的个数。v(3)putback()函数函数v其调用形式为:其调用形式为:vcin.putback(ch);v其作用是将前面用其作用是将前面用get()或或getline()函函数从输入流中读取的字符数从输入流中读取的字符ch返回到输返回到输入流,插入到当前指针
23、位置,以供后入流,插入到当前指针位置,以供后面读取。面读取。v课本课本302页页【例例9-9】putback()函数函数的用法。的用法。v(4)ignore()函数函数vignore()函数的作用是跳过输入流中函数的作用是跳过输入流中n个字符,或个字符,或在遇到指定的终止字符时提前结束(此时跳过包在遇到指定的终止字符时提前结束(此时跳过包括终止字符在内的若干字符)。括终止字符在内的若干字符)。v其调用形式为:其调用形式为:vcin.ignore(int n=1,char&ch=EOF)v其中,其中,n为字符个数,为字符个数,ch为终止字符。也可以不为终止字符。也可以不带参数,带参数,n默认值为
24、默认值为1,终止字符默认为,终止字符默认为EOF,如:,如:vignore(5,A);/跳过输入流中跳过输入流中5个字符,遇个字符,遇A后后就不再跳了就不再跳了v课本课本303页页【例例9-10】用用ignore()函数跳过输入流函数跳过输入流中的字符。中的字符。v以上介绍的各个成员函数,不仅可以以上介绍的各个成员函数,不仅可以用用cin流对象来调用,而且也可以用流对象来调用,而且也可以用istream类的其他流对象来进行调用。类的其他流对象来进行调用。9.3 输入运算符和输出运算符输入运算符和输出运算符及其重载及其重载9.3.1 输入运算符输入运算符输入运算符输入运算符“”也称为流提取运算符
25、,它是一个二也称为流提取运算符,它是一个二目运算符,有两个操作数,左操作数是目运算符,有两个操作数,左操作数是istream类的一类的一个对象,右操作数既可以是一个预定义的变量,也可个对象,右操作数既可以是一个预定义的变量,也可以是重载了该运算符的类对象。因此,输入运算符不以是重载了该运算符的类对象。因此,输入运算符不仅能够识别预定义类型的变量,如果某个类中重载了仅能够识别预定义类型的变量,如果某个类中重载了这个运算符,它也能识别这个类的对象。这个运算符,它也能识别这个类的对象。在使用输入运算符时需要注意以下几点:在使用输入运算符时需要注意以下几点:(1)在默认情况下,运算符)在默认情况下,运
26、算符“”跳过空白符,然跳过空白符,然后读入与输入变量类型相对应的值。因此,给一组变后读入与输入变量类型相对应的值。因此,给一组变量输入值时可以用空格或换行符把输入的数值间隔开。量输入值时可以用空格或换行符把输入的数值间隔开。(2)当输入字符串时,运算符)当输入字符串时,运算符“”的作用是跳过的作用是跳过空白符,读入的字符串中不要有空格,否则认为是结空白符,读入的字符串中不要有空格,否则认为是结束。束。(3)不同类型的变量一起输入时,系统除了)不同类型的变量一起输入时,系统除了检查是否有空白符外,还完成输入数据与检查是否有空白符外,还完成输入数据与变量类型的匹配。如:变量类型的匹配。如:int
27、n;float x;cinnx;如果输入:如果输入:33.33 22.22则得到的结果为则得到的结果为n=33,x=0.33.(4)输入运算符采用左结合方式,可以将多)输入运算符采用左结合方式,可以将多个输入操作组合到一个语句中。个输入操作组合到一个语句中。9.3.2 输出运算符、输出运算符、输出运算符输出运算符“”也称为流插入运算符,它是一个二也称为流插入运算符,它是一个二目运算符,有两个操作数目运算符,有两个操作数,左操作数是左操作数是ostream类的一类的一个对象,右操作数既可以是一个预定义的变量,也可个对象,右操作数既可以是一个预定义的变量,也可以是重载了该运算符的类对象。因此,输出
28、运算符不以是重载了该运算符的类对象。因此,输出运算符不仅能够识别预定义类型的变量,如果某个类中重载了仅能够识别预定义类型的变量,如果某个类中重载了这个运算符,它也能识别这个类的对象。这个运算符,它也能识别这个类的对象。在使用输出运算符时需要注意以下几点:在使用输出运算符时需要注意以下几点:(1)输出运算符也采用左结合方式,可以将多个输)输出运算符也采用左结合方式,可以将多个输入操作组合到一个语句中。入操作组合到一个语句中。如如:int n=1;double m=1.1;coutn,mendl;输出结果就是:输出结果就是:1,1.1(2)使用输出运算符时,不同类型的)使用输出运算符时,不同类型的
29、数据也可以组合在一条语句中,编译数据也可以组合在一条语句中,编译程序会根据在程序会根据在“”和输和输出运算符出运算符“”和和“”重重载的知识已经在第载的知识已经在第7章中做过详细介绍,章中做过详细介绍,在此不再赘述。在此不再赘述。9.4 C+格式输入和输出格式输入和输出v在输出数据时,为简便起见,往往不在输出数据时,为简便起见,往往不指定输出的格式,而由系统根据输出指定输出的格式,而由系统根据输出数据的类型采取默认的格式,但有时数据的类型采取默认的格式,但有时我们希望数据按指定的格式输出。有我们希望数据按指定的格式输出。有两种方法可以达到此目的:一种是使两种方法可以达到此目的:一种是使用流对象
30、的有关成员函数;另一种是用流对象的有关成员函数;另一种是使用控制符。使用控制符。v9.4.1 用用ios类提供的格式化函数控制类提供的格式化函数控制输入输入/输出格式输出格式1控制格式的标志位控制格式的标志位在在ios类中声明了数据成员类中声明了数据成员long x_flags,它存储控制输入,它存储控制输入/输出格式的输出格式的状态标志,每个状态标志占一位。状态状态标志,每个状态标志占一位。状态标志的值只能是标志的值只能是ios类中定义的课本类中定义的课本305页表页表9-2所列枚举量:所列枚举量:2使用成员函数设置标志字使用成员函数设置标志字ios类中定义了一个数据成员来记录当前格式化的类
31、中定义了一个数据成员来记录当前格式化的状态,即各标志位的设置值,这个数据成员被称为状态,即各标志位的设置值,这个数据成员被称为标志字。格式标志在类标志字。格式标志在类ios中被定义为枚举值。因此中被定义为枚举值。因此在引用这些格式标志时要在前面加上类名在引用这些格式标志时要在前面加上类名ios和域运和域运算符算符“:”。设置这个标志字的成员函数为。设置这个标志字的成员函数为setf()。其调用格式如下:其调用格式如下:stream_obj.setf(ios:flags);这里,这里,stream_obj是要设置格式标志的流对象,是要设置格式标志的流对象,编程时常用的是编程时常用的是cin和和c
32、out。要设置多个标志时,。要设置多个标志时,彼此用位运算符彼此用位运算符“|”来分隔。如来分隔。如:cout.setf(ios:dec|ios:scientific);注意:注意:(1)清除状态标志。)清除状态标志。unsetf()函数函数用来清除一个状态标志。用来清除一个状态标志。函数调用格式为:函数调用格式为:stream_obj.unsetf(ios:flags);这里,把指定的状态标志位置这里,把指定的状态标志位置0,就清除了指定的状态标志。,就清除了指定的状态标志。使用方法与使用方法与setf是类似的。是类似的。(2)取标志状态值。取标志状态值。flags()函数函数用来取当前状态
33、标志。有两用来取当前状态标志。有两种使用方法:种使用方法:stream_obj.flags();stream_obj.flags(ios:flags);不带参数的函数是返回与流相关的当前状态标志值。带参数不带参数的函数是返回与流相关的当前状态标志值。带参数的函数是把状态标志值设置为由参数的函数是把状态标志值设置为由参数flags指定的值,并返回设指定的值,并返回设置前的状态标志值。注意:函数置前的状态标志值。注意:函数setf()是在原有的基础上追加设是在原有的基础上追加设定,而定,而flags()函数是用新值覆盖以前的值。课本函数是用新值覆盖以前的值。课本306页页【例例9-11】用用fla
34、gs()函数设置函数设置161在不同数制下的数值。在不同数制下的数值。3.使用成员函数设置域宽、填充字符、精度使用成员函数设置域宽、填充字符、精度在在ios类中,除了提供了操作状态标志的成员函数外,还类中,除了提供了操作状态标志的成员函数外,还提供了设置域宽、填充字符和对浮点数设置精度的成员函数提供了设置域宽、填充字符和对浮点数设置精度的成员函数来对输出进行格式化。来对输出进行格式化。1设置域宽的成员函数设置域宽的成员函数width()该成员函数由两种形式:该成员函数由两种形式:(1)int width()该函数用来返回当前输出数据时的宽度。该函数用来返回当前输出数据时的宽度。(2)int w
35、idth(int wid)该函数用来设置当前输出数据的宽度为参数值该函数用来设置当前输出数据的宽度为参数值wid,并返,并返回更新前的宽度值。回更新前的宽度值。注:如果输出宽度没有设置,那么默认情况下为数据所注:如果输出宽度没有设置,那么默认情况下为数据所占的最少字符数。所设置的域宽仅对下一个输出流由效,当占的最少字符数。所设置的域宽仅对下一个输出流由效,当一次输出完成后,域宽恢复为一次输出完成后,域宽恢复为0。2设置填充字符的成员函数设置填充字符的成员函数fill()该成员函数也由两种形式:该成员函数也由两种形式:(1)char fill()该函数用来返回当前所使用的填充字符。该函数用来返回
36、当前所使用的填充字符。(2)char fill(char c)带参数的带参数的fill()函数用来设置填充字符为参数函数用来设置填充字符为参数c字符,字符,并返回更新前的填充字符。并返回更新前的填充字符。注意:如果填充字符省略,那么默认填充字符为空注意:如果填充字符省略,那么默认填充字符为空格符。如果所设置的数据宽度小于数据所需的最少字格符。如果所设置的数据宽度小于数据所需的最少字符数,则数据宽度按默认宽度处理。符数,则数据宽度按默认宽度处理。3设置浮点数输出精度的成员函数设置浮点数输出精度的成员函数precision()该成员函数也有两种形式:该成员函数也有两种形式:(1)int preci
37、sion()该函数返回当前浮点数的有效数字的个数。该函数返回当前浮点数的有效数字的个数。(2)int precision(int n)该函数设置浮点数输出时的有效数字个数,并返该函数设置浮点数输出时的有效数字个数,并返回更新前的值。回更新前的值。注意:注意:float型实数最多提供型实数最多提供7位有效数字,位有效数字,double型实数最多提供型实数最多提供15位有效数字,位有效数字,long double型实数最多提供型实数最多提供19位有效数字。课本位有效数字。课本308页页【例例9-12】利用格式化成员函数来设置输出数据的利用格式化成员函数来设置输出数据的格式。格式。9.4.2 用控制
38、符控制输入用控制符控制输入/输出格式输出格式使用使用ios类的成员函数来控制输入或输类的成员函数来控制输入或输出格式时,必须由流对象来进行调用,出格式时,必须由流对象来进行调用,使用不方便,可以使用特殊的、类似于使用不方便,可以使用特殊的、类似于函数的运算符来进行控制,这类运算符函数的运算符来进行控制,这类运算符称为控制符。控制符可以直接嵌入到输称为控制符。控制符可以直接嵌入到输入或输出操作的语句中。入或输出操作的语句中。C+提供的控提供的控制符如课本制符如课本309页表页表9-3所示:所示:v这些控制符是在这些控制符是在iomanip.h中定义的,中定义的,因此如果在程序中使用这些控制符必因
39、此如果在程序中使用这些控制符必须把头文件须把头文件iomanip.h包含进来。看下包含进来。看下面的课本面的课本310页页【例例9-13】用控制符控用控制符控制输出格式。制输出格式。9.5 文件操作与文件流文件操作与文件流9.5.1 文件的概念文件的概念v我们前面讨论的输入输出是以系统指定的标准设我们前面讨论的输入输出是以系统指定的标准设备备(输入设备为键盘,输出设备为显示器输入设备为键盘,输出设备为显示器)为对象为对象的。在实际应用中,常以磁盘文件作为对象。即的。在实际应用中,常以磁盘文件作为对象。即从磁盘文件读取数据,将数据输出到磁盘文件。从磁盘文件读取数据,将数据输出到磁盘文件。v所谓所
40、谓“文件文件”,一般指存储在外部介质上数据的,一般指存储在外部介质上数据的集合。一批数据是以文件的形式存放在外部介质集合。一批数据是以文件的形式存放在外部介质上的。操作系统是以文件为单位对数据进行管理上的。操作系统是以文件为单位对数据进行管理的,也就是说,如果想找存储在外部介质上的数的,也就是说,如果想找存储在外部介质上的数据,必须先按文件名找到指定的文件,然后再从据,必须先按文件名找到指定的文件,然后再从文件中读取数据。要向外部介质上存储数据也必文件中读取数据。要向外部介质上存储数据也必须先建立一个文件(以文件名标识),才能向它须先建立一个文件(以文件名标识),才能向它输出数据。外存文件包括
41、磁盘文件、光盘文件和输出数据。外存文件包括磁盘文件、光盘文件和U盘文件。目前使用最广泛的是磁盘文件。盘文件。目前使用最广泛的是磁盘文件。v根据文件中数据的组织形式,文件可分为根据文件中数据的组织形式,文件可分为ASCII文件和二进制文件。文件和二进制文件。ASCII文件也称文本文件,文件也称文本文件,其每个字节存一个其每个字节存一个ASCII代码,表示一个字符。代码,表示一个字符。这样的文件使用比较方便,但占用的存储空间较这样的文件使用比较方便,但占用的存储空间较大。二进制文件,是把内存中的存储形式原样写大。二进制文件,是把内存中的存储形式原样写到外存储器中。使用起来可以节省外存空间和转到外存
42、储器中。使用起来可以节省外存空间和转换时间,但是它的一个字节不对应一个字符。换时间,但是它的一个字节不对应一个字符。v为了实现文件的输入和输出,首先要创建一个文为了实现文件的输入和输出,首先要创建一个文件流,当把这个流和实际的文件相关联时,就称件流,当把这个流和实际的文件相关联时,就称为打开文件。完成输入和输出后要关闭这个文件,为打开文件。完成输入和输出后要关闭这个文件,即取消文件和流的关联。即取消文件和流的关联。9.5.2 文件流类及其流对象文件流类及其流对象在在C+的的I/O流类库中定义了几种文件流类,专门用于对磁盘文件的流类库中定义了几种文件流类,专门用于对磁盘文件的输入输出操作。它们是
43、:输入输出操作。它们是:ifstream类(支持从磁盘文件的输入)、类(支持从磁盘文件的输入)、ofstream类(支持向磁盘文件的输出)和类(支持向磁盘文件的输出)和fstream类(支持对磁盘文件类(支持对磁盘文件的输入输出)。的输入输出)。由前面的知识可以知道在以标准设备为对象的输入输出中,必须定义由前面的知识可以知道在以标准设备为对象的输入输出中,必须定义流对象,如流对象,如cin,cout就是流对象,就是流对象,C+是通过流对象进行输入输出的。是通过流对象进行输入输出的。同理如果以磁盘文件为对象进行输入输出,也必须先定义一个文件流类同理如果以磁盘文件为对象进行输入输出,也必须先定义一
44、个文件流类的对象,通过文件流对象将数据从内存输出到磁盘文件,或者通过文件的对象,通过文件流对象将数据从内存输出到磁盘文件,或者通过文件流对象从磁盘文件将数据输入到内存。流对象从磁盘文件将数据输入到内存。由于由于cin和和cout已在已在iostream.h中事先定义,所以用户不需自己定义中事先定义,所以用户不需自己定义就可以使用。但在通过文件流对象对磁盘文件进行操作时,文件流对象就可以使用。但在通过文件流对象对磁盘文件进行操作时,文件流对象没有事先统一定义,必须由用户自己定义。文件流对象是用文件流类定没有事先统一定义,必须由用户自己定义。文件流对象是用文件流类定义的,看下面的语句:义的,看下面
45、的语句:ofstream outfile;/建立一个输出文件流对象建立一个输出文件流对象outfileifstream infile;/建立一个输入文件流对象建立一个输入文件流对象infile需要注意的是:如果要在程序中建立文件流对象,必须包含头文件需要注意的是:如果要在程序中建立文件流对象,必须包含头文件fstream.h。9.5.3 文件的打开与关闭文件的打开与关闭磁盘文件的打开和关闭使用磁盘文件的打开和关闭使用fstream类中定义的成员函数类中定义的成员函数open()和和close()。1文件的打开文件的打开要对磁盘文件进行读写操作,首先必须要先打开文件。所要对磁盘文件进行读写操作,
46、首先必须要先打开文件。所谓打开文件就是将文件流对象与具体的磁盘文件建立联系,谓打开文件就是将文件流对象与具体的磁盘文件建立联系,并指定相应的使用方式。以上工作可以通过两种不同的方法并指定相应的使用方式。以上工作可以通过两种不同的方法实现:(实现:(1)先说明一个)先说明一个fstream类的对象,再调用该对象的类的对象,再调用该对象的成员函数成员函数open()打开指定的文件。例如,以输出方式打开一打开指定的文件。例如,以输出方式打开一个文件的方法如下:个文件的方法如下:ofstream outfile;/定义定义ofstream类(输出文件流类(输出文件流类)对象类)对象outfileout
47、file.open(f1.dat,ios:out);/使文件流与使文件流与f1.dat文文件建立关联件建立关联上面第上面第1句定义句定义ofstream类对象类对象outfile,第第2句通过句通过outfile调用其成员函数调用其成员函数open(),提供了两个实参:第一个是要,提供了两个实参:第一个是要被打开的文件名,使用文件名时可以包被打开的文件名,使用文件名时可以包括路径,如括路径,如“c:newf1.dat”,如果默,如果默认路径,则默认为当前目录下的文件。认路径,则默认为当前目录下的文件。第二个实参说明文件的访问方式。文件第二个实参说明文件的访问方式。文件访问方式包含多种操作,见课
48、本访问方式包含多种操作,见课本313页页表表9-4所示。所示。(2)在定义文件流对象时同时指定参数在定义文件流对象时同时指定参数在声明文件流类时定义了带参数的构造函数,其中在声明文件流类时定义了带参数的构造函数,其中包含了打开磁盘文件的功能。因此,可以在定义文件包含了打开磁盘文件的功能。因此,可以在定义文件流对象时指定参数,调用文件流类的构造函数来实现流对象时指定参数,调用文件流类的构造函数来实现打开文件的功能。如要实现(打开文件的功能。如要实现(1)中说明的以输出方式)中说明的以输出方式打开一个文件,方法如下:打开一个文件,方法如下:ofstream outfile(f1.dat,ios:o
49、ut);一般多用此形式,相比(一般多用此形式,相比(1)来说比较方便。作用)来说比较方便。作用与与open()函数相同,参数含义相同。函数相同,参数含义相同。注意:对于表注意:对于表9-4中的访问方式可以用中的访问方式可以用“位或位或”运算运算符符“|”对输入输出方式进行组合。另外,如果打开操作对输入输出方式进行组合。另外,如果打开操作失败,失败,open函数的返回值为函数的返回值为0(假),如果是用调用(假),如果是用调用构造函数的方式打开文件的,则流对象的值为构造函数的方式打开文件的,则流对象的值为0。2关闭磁盘文件关闭磁盘文件当结束一个磁盘文件的读写操作后,当结束一个磁盘文件的读写操作后
50、,应关闭该文件。关闭文件用成员函数应关闭该文件。关闭文件用成员函数close()。如:。如:outfile.close();看课本看课本314页页【例例9-14】文件操作演文件操作演示程序。示程序。9.5.4 对文本文件的操作对文本文件的操作如果文件的每一个字节中均以如果文件的每一个字节中均以ASCII代码形代码形式存放数据,即一个字节存放一个字符,这式存放数据,即一个字节存放一个字符,这个文件就是个文件就是ASCII文件(或称文本文件)。程文件(或称文本文件)。程序可以从序可以从ASCII文件中读入若干个字符,也可文件中读入若干个字符,也可以向它输出一些字符。以向它输出一些字符。对文本文件的
侵权处理QQ:3464097650--上传资料QQ:3464097650
【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。