收藏 分享(赏)

13 输入输出流.ppt

上传人:scg750829 文档编号:9110506 上传时间:2019-07-24 格式:PPT 页数:67 大小:1.19MB
下载 相关 举报
13 输入输出流.ppt_第1页
第1页 / 共67页
13 输入输出流.ppt_第2页
第2页 / 共67页
13 输入输出流.ppt_第3页
第3页 / 共67页
13 输入输出流.ppt_第4页
第4页 / 共67页
13 输入输出流.ppt_第5页
第5页 / 共67页
点击查看更多>>
资源描述

1、第13章 输入输出流,13.1 C+的输入输出 13.2 标准输出流 13.3 标准输入流 13.4 文件操作与文件流,13.1 C+的输入和输出(I/O),输入和输出,要看以什么为对象 以标准I/O设备为对象 从键盘、鼠标得到的数据是进入内存的,该数据是输入数据。 将数据从内存送到显示器、打印机等,该数据是输出数据。 以外存磁盘文件为对象 内存中的数据存储到磁盘文件中,叫输出文件; 从磁盘文件中的数据装载入内存中,叫输入文件。 以内存中指定的空间作为对象 常指定一个字符数组作为存储空间,这种I/O称为字符串的输入输出。 C+采取不同的方法实现以上三种I/O。,标准I/O,文件I/O,串I/O

2、,数据之间的传输过程称作流(stream) 输入流表示数据从某个载体或设备传送到内存 输出流表示数据从内存传送到某个载体或设备,C+的输入输出流,在进行I/O操作时 首先进行“打开”操作,使流和文件发生联系 建立联系后的文件才允许数据流入或流出 I/O结束后,使用“关闭”操作使文件与流断开联系。 C+将I/O流定义为类流类。属于流类的对象是流对象 系统已经以运算符或函数的形式做好了对标准外设(键盘、显示器、打印机、文件)的接口,使用时只需按照要求的格式调用即可。 如:cin 标准输入流对象。cout 标准输出流对象。,C+的输入输出流,类的定义,类是一种复杂的数据类型 它是将不同类型的数据和与

3、这些数据相关的运算封装在一起的集合体。 它使类中的数据得到很好的“保护”,在大型程序中不会被随意修改。 在C+中,结构体类型只是类的一个特例,实例化,圆类数据成员半径成员函数置半径值求周长求面积,类的变量即为对象。 对象是类的实例,C+的各种I/O流类库,C+为实现数据的I/O定义了一个庞大的类库。它包括的类主要有,C+ I/O类库中的其他类,包含头文件,在一个程序中包含一个头文件的命令格式为 #include 常用的I/O类库有,在iostream中定义的4个流对象 cin,cout,cerr, clog,13.2 标准输出流,标准输出流流向标准输出设备(显示器)的数据 cout流对象在控制

4、台(显示器)输出 用流插入运算符“”向cout输出数据. 如: cout “a=” a endl;cout 数据1 数据2 数据3; cerr流对象在控制台(显示器)输出错误信息 用流插入运算符“”向cerr输出数据. 如: cerr “除数为0, 出错!” endl;cerr的用法与cout类似. cout流对象与cerr流对象的不同之处 cout的输出默认是显示器,但可以被重定向为输出到磁盘文件 cerr只能定向输出到显示器,例13.1 解一元二次方程ax2+bx+c=0 的解,void main( ) float a, b, c, disc;cout a b c;if (a=0) cer

5、r “ a=0, 不是二次方程,出错!”endl;else disc=b*b-4*a*c;if (disc0) cerr“二次方程无实根。”endl;else cout“x1=”(-b+sqrt(disc)/(2*a)endl;cout “x2=”(-b-sqrt(disc)/(2*a)endl; ,标准输出流,标准输出流流向标准输出设备(显示器)的数据 clog流对象在控制台(显示器)输出错误信息. 用流插入运算符“”向clog输出数据. 如: clog “除数为0, 出错!” endl;clog的用法与cerr类似. clog流对象与cerr流对象的不同之处 cerr是不经过缓冲区,直接向

6、显示器输出有关信息。 clog的输出先存储在缓冲区,遇到缓冲区满或遇到endl时才向显示器输出。,使用控制符控制格式输出,#include #include using namespace std; void main( ) int a;cout a; / a=34cout“dec:”decaendl; cout“hex:”hexaendl; cout“oct:”octaendl; coutsetfill(*)setw(10)decaendl; ,例13.2 用控制符控制输出格式,dec:34,hex:22,oct:42,*34,用流对象的成员控制格式输出,说明: cout.width(n)

7、与格式控制符setw(n)相似 cout.fill(c) 与格式控制符setfill(c)相似,13.3 标准输入流,标准输入流从标准输入设备(键盘)流向程序的数据.cin流对象int a,b;cin ab; / 从键盘输入2个整数 当输入时 遇到无效的字符 或遇到文件结束符 ctrl+z 时 cin处于出错状态,无法正常提取数据(cin=false).if (!cin)cout“输入出错”;,21 abc,用于字符输入的流成员函数,不带参数的get函数cin.get( ) 功能 从输入流提取1个字符; 函数返回值就是该字符. 若遇到文件结束符,则返回值为EOF,即 -1. 如: char c

8、h;while ( (ch=cin.get()!=EOF)cout.put(ch);键盘输入: 显示: 键盘输入:,I study C+.,(程序结束),I study C+. ,Ctrl+Z,EOFEnd Of File,字符输出的流成员函数,功能在显示器上显示一个字符,用于字符输入的流成员函数,2. 带1 个参数的get函数cin.get(ch) 功能 从输入流提取1个字符放入ch; 函数返回值就是非0值 若遇到文件结束符,则返回值为0 如: char ch;while ( cin.get(ch)!=0)cout.put(ch);键盘输入: 显示: 键盘输入:,I study C+.,(程

9、序结束),I study C+. ,Ctrl+Z,用于字符输入的流成员函数,3. 带3 个参数的get函数cin.get(字符数组, 字符个数n, 终止字符) 或 cin.get(字符指针, 字符个数n, 终止字符) 功能 从输入流提取n-1个字符放入数组; 函数返回值就是非0值 若遇到文件结束符,则返回值为0 如 char str20;cin.get(str, 10,“n”);coutstr;键盘输入: 显示:,I study C,I study C+. ,用于字符输入的流成员函数,4. cin.getline函数可输入一行字符cin.getline(字符数组, 字符个数n, 终止字符) 或

10、 cin.getline(字符指针, 字符个数n, 终止字符) 功能 从输入流提取n-1个字符放入数组; 函数返回值就是非0值 若遇到文件结束符,则返回值为0 如 char str20;cin.get(str, 10,“n”);coutstr;键盘输入: 显示:,I study C,I study C+. ,cin.get() 与 cin.getline() 的比较,cin.get(字符数组, 字符个数n, 终止字符) cin.getline(字符指针, 字符个数n, 终止字符) 相同之处: 从输入流提取n-1个字符放入数组, 函数返回值是非0值. 若遇到文件结束符,则返回值为0. 不同之处:

11、 当读到终止字符时, cin.getline()将指针移到终止字符之后。 cin.get() 将指针移到终止字符处。 则下次继续读取时的位置就不同。,13.4 文件操作与文件流,文件 存储在某种设备(磁带、光盘、软盘或硬盘)上数据的集合; 对用户来说,文件分成两大类: 程序文件数据文件 从文件中数据的组织形式来分: ASCII文件(文本文件)二进制文件,文本文件和二进制文件,文本文件(ASCII文件): 文件中的内容都是字符, 以ASCII码形式存在文件内. 如: 12345在文本文件中是以 1,2,3,4,5共 5个字符形式存储的 二进制文件: 文件中的内容是以数据的二进制形式存储的. 如:

12、 12345在二进制文件中按1个整数类型以二进制形式存储,占4个字节空间,文件流 C+在头文件fstream.h中定义了C+的文件流类体系 ,当程序中使用文件时,要包含头文件fstream.h 。,当使用文件时,在程序头有:#include 其中定义了各种文件操作运算符及函数。,文件流,用标准流进行I/O时,系统自动地完成数据类型的转换。 对于输入流,要将输入的字符序列形式的数据变换成计算机内部形式的数据(二进制或ASCII)后,再赋给变量,变换后的格式由变量的类型确定。 对于输出流,将要输出的数据变换成字符串形式后,送到输出流(文件)中。,程序对文本文件的操作与对键盘、显示器的操作比较:,在

13、涉及文本文件的操作时,将输入文件看成键盘,将输出文件看成显示器,格式不变。只需在程序中增加打开与关闭文件的语句。,C+角度的输入和输出,流充当了程序和流源或流目标之间的桥梁; 使得C+程序可以以相同的方式对待来自键盘的输入和来自文件的输入; 同理,通过使用流,C+程序处理输出的方式将独立于其去向;,简单的文件I/O,要让程序将数据写入文件,必须: 创建一个ofstream对象来管理输出流; 将该对象与特定的文件关联起来; 以使用cout的方式使用该对象,唯一的区别是:输出将进入文件,而不是屏幕;,#include /必须包含的头文件 using namespace std; void main

14、() int a=12 , b=34;ofstream fout; /定义ofstream类对象foutfout.open(“c:c_05temptest.dat“, ios:out); /使文件流与test.dat建立关联foutaendl;foutbendl;fout.close( ); /将输出文件流所关联的磁盘文件关闭 ,例 将int a=12, b=34写到磁盘文件中,读取文件,#include using namespace std; void main( ) int a,b;ifstream infile;infile.open(“c:c_05temptest.dat“, ios

15、:in);infileab;cout“a=“aendl;cout“b=“bendl;infile.close( ); ,文本文件的打开与关闭,在文件操作前,需要将程序与被操作的文件联系起来,使程序可以“引用”文件。 在程序内定义一个文件类的对象,由该对象与文件发生联系,程序内所有的与文件的操作都是对该对象的操作。fstream infile , outfile;定义两个对象,可以联系两个输入输出文件ifstream infile;定义一个对象只能联系输入文件ofstream outfile;定义一个对象只能联系输出文件,定义用于输入的文件对象,定义用于输出的文件对象,定义用于输入输出的文件对象

16、,文件对象与包含文件头的关系,文件的打开与关闭,如何使文件类的对象与欲操作的文件发生联系? 用对象打开文件 方法一:ofstream outfile; /定义输出文件类对象outfile.open(“d:mydoca1.dat”);格式: 文件流对象.open(文件名) 方法二:定义对象时直接初始化 ofstream outfile(“d:mydoca1.dat”);,打开文件“a1.dat”用于输出,并将此文件与输出文件类对象outfile建立联系 今后在程序中,用到文件“a1.dat”的地方就用outfile来代替。,文件的打开,在打开文件后,都要判断打开是否成功 若打开成功,则文件流对象

17、值为非零值; 若打开不成功,则其值为0。 ifstream pfile1; /定义输入文件类对象 ofstream pfile2; /定义输出文件类对象 pfile1.open(“file1.txt”); pfile2.open(“file2.txt”,); if (!pfile1) /若为0,打开文件操作失败cerr ”不能打开输入文件:file1.txt”endl; exit(1); if (!pfile2)cerr ”不能打开输出文件:file2.txt”endl; exit(1);,打开输入文件时,文件必须存在,打开输出文件时, 若文件不存在,则建立文件; 若文件存在,则删除原文件的内

18、容,使其成为一个空文件。,将文件类对象看成键盘和显示器即可。,ifstream infile; /定义输入文件类对象 infile.open(“myfile1.txt”); /利用函数打开某一文件 float x , y; infilexy;,myfile1.txt,3 4,内存,infile,x,y,3,4,用infile代替myfile1.txt进行操作。,如何从文件中读出数据?,ifstream outfile; /定义输出文件类对象 infile.open(“myfile2.txt”); /利用函数打开某一文件float x3 , y4; outfilextyendl;,myfile2

19、.txt,内存,outfile,x,y,3,4,用outfile代替myfile2.txt 进行操作。,3,4,如何把数据写到文件?,ifstream infile; ofstream outfile; infile.open(“myfile1.txt”); outfile.open(“myfile2.txt”); float x,y; infilexy; outfilextyendl; infile.close(); outfile.close();,myfile1.txt,3 4,内存,infile,x,y,3,4,myfile2.txt,outfile,3,4,infile.close(

20、 ); outfile.close( );,用完文件后,使用成员函数关闭文件,#include #include using namespace std; void main( ) int a10;ofstream outfile(“f1.dat”); /定义文件流对象,打开文件f1.datif (!outfile) /若打开失败,返回 0值 cerrai;outfileai ; /向文件f1.dat输出数据outfile.close(); /关闭文件f1.dat ,例13.11 有一个整型数组,含10个元素,从键盘输入10个整数给数组,将此数组送到磁盘文件地f1.dat中存放。,#inclu

21、de #include void main( ) int a10,max,i,order;/定义输入文件流对象,以输入方式打开f1.dat ifstream infile(“f1.dat”);if (!infile) cerrai;/从文件读入数据到a数组中coutai“ ”; /显示顺序显示10个数coutendl;max=a0; order=0;,例13.12 从例13.11建立的数据文件f1.dat中读入10个整数放在数组中,找出并输出10个数中的最大者和它的序号。,for(i=1;imax)max=ai; /存放最大值到max中order=i; /存最大值序号到order中coutma

22、x=maxendl;coutorder=orderendl;infile.close( ); ,33 65 87 2 5 11 44 88 99 0 max=99 order=8,void main( ) int a10;ifstream infile; /定义输入文件类ofstream outfile; /定义输出文件类infile.open(“file1.txt”); /打开输入文件“file1.txt”outfile.open(“file2.txt”); /打开输出文件“file2.out”for(int i=0;iai; /将“file1.txt”中的十个整数输入到ai中for(i=0

23、;i10;i+)outfileait;/将ai中的十个数输出到文件“file2.txt”outfileendl;infile.close();/关闭输入文件outfile.close();/关闭输出文件 ,输入文件“file1.txt”必须存在,且在其中有十个整数,将数据从一文件复制到另一文件,文件输入输出方式设置值,说明: 每一个打开的文件都有一个文件指针。 可以用“位或”运算符“|”对I/O方式进行组合。ios:in | ios:out 以输入功或输出方式打开文件,文件可R/W 如果打开操作失败,open函数的返回值为0(假) 如果是用调用构造函数的方式打开文件的,则流对象的值为0。,该对

24、象既能定义输入文件对象,又能定义输出文件对象 文件流对象.open(文件名,文件打开方式),用类fstream定义文件对象时的操作,用类fstream定义文件对象时的操作,fstream pfile1,pfile2;/定义了两个文件类的对象 /pfile1联系到“file1.txt”,用于输入 pfile1.open(“file1.txt”, ios:in );/pfile2联系到“file2.txt”,用于输出 pfile2.open(“file2.txt”, ios:out); char ch; pfile1ch; /输入 pfile2ch; /输出 pfile1.close(); pfi

25、le2.close();,char ch, str300; ifstream infile(“myfile1.txt”); ofstream outfile(“myfiel2.txt”);,说明: 从文件输入一字符或一行字符,当输入至文件尾时,函数返回值为0,可以据此来判断循环结束。,涉及到字符串的文件读写,void main( ) char filename1256,filename2256;coutfilename1; 输入文件(源文件)名coutfilename2; 输出文件(目的文件)名ifstream infile(filename1); /用构造函数打开文件ofstream out

26、file(filename2);char ch;while(infile.get(ch) 从源文件中读取一个字符,至文件尾停止循环outfile.put(ch); 将该字符输出至目的文件infile.close(); 关闭文件outfile.close(); ,实现两个ASCII文件拷贝的程序,文件的输入和输出,下面程序将data.txt文件中的数据全部读出并累加求和后,结果保存到output.txt文件中. #include using namespace std; void main() ifstream fin(“c:data.txt”);ofstream fout(“c:output.

27、txt”);int t, s=0;while (fint)s+=t;foutsendl; fin.close(); fout.close(); ,13.4.5 对二进制文件的操作,若在文件的打开方式中没有特别说明,打开的文件均为ASCII码文件,若要打开二进制文件,则要特别说明并用特定的读写函数。,fstream infile,outfile; infile.open(“inf1.dat”, ios:in| ios:binary);,outfile.open(“outf1.dat”, ios:out| ios:binary);,文件名,输入方式打开,二进制文件,文件名,输出方式打开,二进制文件

28、,1. 用成员函数来读写二进制文件,对二进制文件的读写主要用fstream类的成员函数read和write来实现。这两个成员函数的原型为read(char *buffer, int len); write(const char * buffer, int len); 字符指针buffer指向内存中一段存储空间。 len是读写的字节数。 调用的方式为 infile. read(p2,30); outfile. write(p1,50);,例13.14 将一批数据以二进制形式存放在磁盘文件中。 #include #include using namespace std; struct studen

29、t char name20; int num;int age;char sex; ; void main( ) student stud3=“Li”,1001,18, f,“Fun”,1002,19,m,“Wang”,1004,17,f; ofstream outfile(“stud.dat”, ios:out | ios:binary);if(!outfile)cerropen error!endl;abort( ); /退出程序,for(int i=0; i3; i+)outfile.write(char*) ,可以一次输出整个数组到磁盘文件: outfile.write(char*) 用

30、此方法一次可以输出一批数据,效率较高。 在输出的数据之间不必加入空格,在一次输出之后也不必加回车换行符。 在以后从该文件读入数据时不是靠空格作为数据的间隔,而是用字节数来控制。,例13.14 将一批数据以二进制形式存放在磁盘文件中,例13.15 将刚才以二进制形式存放在磁盘文件中的数据读入内存并在显示器上显示。 #include #include using namespace std; struct student string name; / 最好改为 char name20;int num;int age;char sex; ; void main( ) student stud3;in

31、t i;ifstream infile(stud.dat, ios:in | ios:binary);if(!infile)cerropen error!endl;abort( ); ,for(i=0;i3;i+)infile.read(char*) ,问题: 能否一次读入文件中的全部数据,如infile.read( (char*),运行时显示器上显示,NO.1 name: Li num: 1001 age: 18 sex: fNO.2 name: Fun num: 1001 age: 19 sex: mNO.3 name: Wang num: 1004 age: 17 sex: f,可以!,

32、infile.eof( ) 当到达文件结束位置时,该函数返回一个非零值;否则返回零。,fstream infile; infile.open(“data1.dat”,ios:in|ios:binary); if(!infile) cerr“Open Error!n”; exit(1); char str300; while(!infile.eof()infile.read(str, 300);,判断打开是否出错,判断是否读到文件尾,判断二进制文件是否读到文件尾?,void main( ) char filename1256,filename2256; char buff4096;/设置输入缓冲

33、区 cout filename1; cout filename2; fstream infile,outfile; infile.open(filename1,ios:in | ios:binary); outfile.open(filename2,ios:out | ios:binary); int n; while (!infile.eof() /文件不结束,继续循环infile.read(buff,4096); /一次读4096个字节n=infile.gcount(); /取实际读的字节数outfile.write(buff,n); /按实际读的字节数写入文件 infile.close(

34、); outfile.close(); ,实现两个二进制文件拷贝的程序,2. 与文件指针有关的流成员函数,当一打开文件,文件指针位于文件头,并随着读写字节数的多少顺序移动。,对于二进制文件(或文本文件)允许对指针进行控制,使它按用户的意图移动到所需的位置,以便在该位置上进行读写。,2. 与文件指针有关的流成员函数,文件流提供一些有关文件指针的成员函数:infile.gcount( ) /返回最新一次输入的字节数 struct student char name20; int num;int age;char sex; stud; 如:ifstream infile(“c:data.txt”);

35、infile.read( ,infile.tellg( ) 返回输入文件指针的当前位置(long型整数,以字节为单位,从0算起)infile.seekg( 文件中的位置 );/将输入文件的指针移到指定的位置infile.seekg( 位移量,参照位置 ); /将输入文件指针移到从参照位置为基础移动若干字节位置Outfile.tellp( ) 返回输出文件指针的当前位置Outfile.seekp( 位移量,参照位置 ); /将输出文件指针移到从参照位置为基础移动若干字节位置,与文件指针有关的流成员函数,参照位置ios:beg 文件开头begin(默认值)ios:cur 指针当前位置current

36、ios:end 文件末尾(已超出文件尾) 如:infile.seekg(100); 输入文件指针移到文件第101字节处 (第1个字符的位置是0)infile.seekg(- 50, ios:cur ); 当前位置回移50个字节,与文件指针有关的流成员函数,说明 异常指针已在文件尾,还要读数据,则eof()=1; 打开文件失败;其之后的相关操作都会失效。,fin.seekg(0,ios:beg); /将文件指针移到文件头cout“begin=”fin.tellg()endl; /显示文件指针当前位置0fin.seekg(0,ios:end); /将文件指针移到文件尾fin.get(); / 到文

37、件尾还要读数据,eof出现。fin状态异常cout“end=“fin.tellg( )“eof( )=“fin.eof()endl; / 显示:end= -1 eof( )=1fin.seekg(0,ios:beg); / 由于fin状态异常,seekg不起作用 cout“begin=”fin.tellg()endl; / 显示:begin= -1,当文件对象发生操作异常时,注意 异常指针已在文件尾,还要读数据,则eof发生; 要使其后操作有效,要用clear( )清除之前的错误状态,fin.seekg(0,ios:beg); /将文件指针移到文件头cout“begin=”fin.tellg(

38、)endl; /显示文件指针当前位置0fin.seekg(0,ios:end); /将文件指针移到文件尾fin.get(); / 到文件尾还要读数据,eof出现。fin状态异常cout“end=“fin.tellg( )“eof( )=“fin.eof()endl; / 显示:end= -1 eof( )=1 fin.clear( ); / 将fin的异常状态清除fin.seekg(0,ios:beg); / 由于fin状态异常,seekg不起作用 cout“begin=”fin.tellg()endl; / 显示:begin= 0,当文件对象发生操作异常时,3. 随机访问二进制数据文件,例1

39、3.16 有5个学生的数据,要求: (1) 把它们存到磁盘文件中; (2) 将磁盘文件中的第1,3,5个学生数据读入程序,并显示出来; (3) 将第3个学生的数据修改后存回磁盘文件中的原有位置。 (4) 从磁盘文件读入修改后的5个学生的数据并显示出来。,一般情况下读写是顺序进行的,即逐个字节进行读写。 但是对于二进制数据文件来说, 可用前面的成员函数移动指针,随机地访问文件中任一位置上的数据,还可以修改文件中的内容。,例13.16 程序完成任务流程,内存,5个学生的数据stud5,磁盘文件stud.dat,3个学生数据 stud13,5个学生的数据stud5,要实现以上要求,需要解决3个问题:

40、 由于同一磁盘文件在程序中需要频繁地进行输入和输出,因此可将文件的工作方式指定为输入输出文件,即ios:in|ios:out|ios:binary 正确计算好每次访问时指针的定位,即正确使用seekg或seekp函数。 infile.seekg( 位移量,参照位置 ); /将输入文件指针移到从参照位置为基础移动若干字节位置 Outfile.seekp( 位移量,参照位置 ); /将输出文件指针移到从参照位置为基础移动若干字节位置 (3) 正确进行文件中数据的重写(更新)。,3. 随机访问二进制数据文件,#include #include using namespace std; struct

41、student int num;char name20;float score; ; void main( ) student stud5= 1001,Li, 85, 1002,Fun, 97.5,1004,Wang,54,1006,Tan, 76.5,1010,ling, 96 ;fstream iofile(stud.dat, ios:in | ios:out | ios:binary); /用fstream类定义输入输出二进制文件流对象iofile,例13.16程序实现,if(!iofile)cerropen error!endl;abort( ); for(int i=0;i5;i+)

42、 /向磁盘文件输出5个学生的数据iofile.write(char *),stud2.num=1012; strcpy(stud2.name,Wu);stud2.score=60;iofile.seekp(2*sizeof(stud0),ios:beg); /定位于第3个学生数据的开头iofile.write(char *) ,1001 Li 85 1004 Wang 54 1010 ling 961001 Li 85 1002 Fun 97.5 1012 Wu 60 1006 Tan 76.5 1010 ling 96,运行情况如下,(第1个学生数据) (第3个学生数据) (第5个学生数据)(输出修改后5个学生数据)(已修改的第3个学生数据),

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报