《第10章C的输入输出流.ppt》由会员分享,可在线阅读,更多相关《第10章C的输入输出流.ppt(56页珍藏版)》请在三一文库上搜索。
1、C+程序设计,第10章 C+的输入输出流,流与流对象 标准输出流 标准输入流 输入输出的格式化 文件处理 字符串流,主要内容,流与流对象,1、流的引入 scanf(“%d“,2、流的基本概念 流:数据从一个对象流动到另一个对象,这种 流动抽象为流。 流的操作:建立流、删除流、提取(读操作/输 入)、插入(写操作/输出)。,3、C+流的继承结构,流与流对象,C+的输入输出操作由它所提供的一个I/O流类的类库 来实现,该类库是用继承的方法建立起来的,主要有 streambuf和ios两个平行的基类。 streambuf类主要负 责缓冲区的处理,同时也为ios基类提供缓冲支持。Ios 类是一个抽象基
2、类,主要提供I/O所需的公共操作,其 层次结构图如图10-1。,流与流对象,标准流是C+预定义的对象,主要提供内存与外部设备 进行交互的功能,包括数据提取、插入、解释及格式处 理,同时为这种数据交换提供必要的缓冲支持,其关系 如图 10-2。,流与流对象,系统预定义了4个流类对象,供用户使用,见表10-1。,【例10.1】计算一个数的平方根。,#include #include using namespace std; int main() double x; coutx; /cin的用法 if(xx; clog“square root is: “sqrt(x)endl; / clog的用法
3、return 0; ,1、使用成员函数put( )输出一个字符,格式为:cout.put(char c)或cout.out(const char ch );,2、使用成员函数write( )输出字符串,格式为:cout.write(const char *str,int n);,说明:,这些成员函数既可用于文本流,也可用于二进制流,尤其适用于二进制流。,标准输出流,【例10.2】put( )函数使用,void main() char ch1=A,ch2=B; coutA,Bendl; cout.put(ch1).put(,).put(ch2).put(n); cout.put(A).put(,
4、).put(B).put(n); ,【例10.3】write( )函数使用,void main() char *str1=“1234567890“; /字符指针 char str2=““; /字符数组 cout.write(str1,10).put(n); /输出全部字符 cout.write(str2,strlen(str2).put(n); /输出前6个字符 cout.write(“ABCDEFGHIJK“,6)endl; ,结果: 1234567890 ABCDEF,1、使用成员函数get( )获取一个字符,格式为:cout.get(char ,标准输入流,注意:get( )在获取字符
5、时不忽略空白字符,即输入流中的空白字符也会被当作有效字符读入。,2、使用成员函数getline( )获取多个字符,格式为: cout.getline(char *buf,int size,char delim=n);c,getline( )最多可读取Limit-1个字符;,从输入流中读取Limit-1个字符后; 从输入流中读取换行符或其他终止符后; 从输出流中读取到文件或输入流结束符后; getline( )通常用来读取一行字符:,3.getline( )函数结束操作的条件:,标准输入流,【例10.4】get( )函数使用,void main() int cnt=0; char ch; cou
6、t“input a sentence:n“; while (ch=cin.get()!=EOF) /按ctrl+Z结束输入 coutch; /输出到屏幕上 cnt+; /字符计数 coutcntendl; ,【例10.4】get( )函数使用,执行结果: input a sentence: i love you everyoneZ(注:此行是用户输入的) i love you everyoneZ(注:此行是程序显示在屏幕上的) 19,程序中的EOF(End Of File)是iostream中预定义的符号常 量,意思是文件结尾。,编程时往往把get( )与put( )结合起来使用。,【例10.
7、5】用getline( )函数读入一行字符。,void main() char ch20; coutch; cout“sentence1 is: “chendl; cin.getline(ch,20,/); /读19个字符或遇到/结束 cout“sentence2 is: “chendl; cin.getline(ch,20); /读19个字符或遇到n结束 cout“sentence3 is: “chendl; ,【例10.5】用getline( )函数读入一行字符。,程序运行结果: input a sentence: I like C+/I study hard(注:此为用户输入) sent
8、ence1 is: I sentence2 is: like C+ sentence3 is: I study hard,一般可用两种方式来实现:一是使用格式控制符, 二是使用流对象的成员函数。,1.设置标识字,(1).标识常量,ios类中用标识字来记录当前流格式化状态,标识字的 每一位用于记录(或控制)一种格式,每种格式都定 义了对应的枚举常量,在编程时,可以使用标识常量 或直接用对应十六进制值设置输入输出格式。,输入输出的格式化,(2). ios中控制格式的成员函数,ios类有6个公有成员函数可以直接操作该标识字,他们 为 :long flags( ) const(函数返回流的格式标志),
9、 long setf (long lFlags )(设置参数lFlags指定的标识位, 并返回更新前的标识字),long unsetf (long lFlags ) (清除流的格式标志),char fill (char cFill )(设置或 读取流的填充字符),int precision (int np )(设置或读 取流的浮点数显示精度),int width( int nw)(设置或 读取流的输出宽度)。,输入输出的格式化,10.13 5.36 653.7 1234.24,cout.fill(*);,*10.13 *5.36 *653.7 *1234.24,【例10.6】用width控制输
10、出宽度。,void main( ) double a = 10.13,5.36,653.7,1234.24 ; for(int i=0;i4;i+) cout.width(10); cout ai n; ,特别说明 :,由于标识字的每一位都表示一种格式,格式位之间会有相互 依赖或相互排斥的关系,比如:dec、hex及oct在同一时刻只能 有一种起作用,所以为安全起见,在设置一个位前应该消除其 它有互斥的位。可以通过ios中的公有静态符号常量来实现 。,输入输出的格式化,例如:cout.setf(ios:oct,ios:basefield); 即用ios:basefield先清 除格式位,并设置
11、为八进制输出。如果要同时设置几个不互斥 的标识位,可用位运算符(“”)连接,如:cout.setf(ios:oct|ios:left);,程序运行结果: output with fixed: +3.14 output with scientific: 3.1429e+005,【例10.7】 浮点数输出的格式化。,void main() double x=22.0/7; cout“output with fixed:n“; cin.setf(ios:fixed|ios:showpos); cout.precision(3); coutxendl; cout“output with scienti
12、fic:n“; cin.setf(ios:scientific,ios:fixed|ios:showpos); cout.precision(5); coutx*1e5endl;,2.格式控制符,用上述方式进行格式控制有时稍嫌麻烦, 下面引入控 制符(操作算子),以简化对IO控制的编程。这些控 制符在iostream.h及iomanip.h中声明。,(1). iostream中的控制符(见后表10-2),输入输出的格式化,(2). iomanip中的控制符(见后表10-3),输入输出的格式化,输入输出的格式化,【例10.8】 用控制符实现不同基数形式的输入输出。,#include void m
13、ain() int a,b,c; coutdeca; couthexb; coutoctc; cout“output with decimal:n“;,cout“a=“a“,b=“b“,c=“ cendl; cout“output with hexadecimal:n“; couthex“a=“a“,b=“b “,c=“cendl; cout“output with octal:n“; coutoct“a=“a“,b=“b “,c=“cendl; ,【例10.8】 用控制符实现不同基数形式的输入输出。,我们将十进制的126分别用三种进制形式输入,得到以下运行结果: input a with d
14、ecimal:126 input b with hexadecimal:7e (注:即十进制的126) input c with octal:176 (注:即十进制的126) output with decimal: (用十进制形式输出的126) a=126,b=126,c=126 (结果都为126) output with hexadecimal: a=7e,b=7e,c=7e output with octal: a=176,b=176,c=176,【例10.9】 整数的格式化输出,#include #include void main() const int k=12345; couts
15、etw(10)setfill(#) setiosflags(ios:right)kendl; coutsetw(10)setbase(8)setfill(*) resetiosflags(ios:right)setiosflags(ios:left) kendl; ,运行结果: #12345 30071*,注:程序中 setbase(8)相当于 iostream中的控制 符oct,其余类似。,【例10.10】 用控制符实现浮点数输出的格式化,#include #include void main() double x=22.0/7; cout“output with fixed:n“; cou
16、tsetiosflags(ios:fixed|ios:showpos); coutsetprecision(3); coutxendl; cout“output with scientific:n“; coutresetiosflags(ios:fixed|ios:showpos);,coutsetiosflags(ios:scientific); coutsetprecision(5); coutx*1e5endl; ,运行结果: output with fixed: +3.143 output with scientific: 3.14286e+005,文件处理,文件概述 文件的打开与关闭
17、 文本文件读写 二进制文件的读写 随机文件的读写,计算机应用系统通常把一些相关的信息组织起来保存在外部存储器中,称之为文件,并用一个文件名来进行标识。,1、文件概述 文件分为两类,一类是程序文件,一类是数据文件。按文件中数据的组织形式 ,可分为文本文件(字符文件)和内部字二进制文件(字节文件)。而根据文件的存取方式,又可以分为顺序存取文件和随机存取文件。,文件处理,文件操作一般包含三个步骤:打开文件、文件读写、关闭文件。 在C+中定义了如下专门用于文件操作的文件类: 1)ifstream 类:从istream类派生,用于支持磁盘文件的输入; 2)ofstream类:从ostream类派生,用于
18、支持磁盘文件的输出; 3)fstream 类:从iostream类派生,用于支持磁盘文件的输入输出。,文件处理,2.文件的打开与关闭,文件处理,(1).打开文件,文件的打开包括建立文件流对象、与外部文件关联及 指定打开方式等步骤。 open函数的调用形式为: 文件流对象.open(文件名,打开方式); 其中文件名可以包含路径,如果省略了路径,则系统 默认为程序当前所在目录。而打开方式,是用来说明 文件以何种方式打开的,如读、写、读写或者二进制 数据模式等等。,说明:每个被打开的文件都有一个文件指针,其初始位置与 打开方式有关。当指针指到文件结束标志EOF时,成员函数 eof( )的值为非0,代
19、表文件结束。 当有多种打开方式时,同样可用位运算符(“”)进 行连接,如: ios:in|ios:out|ios:binary; /以二进制读/写方式 打开文件 如果文件打开失败,open函数返回值为0(假),据此 可判断文件打开是否成功。,文件处理,对于路径问题,比如“C:CPPtest.txt”,由于“” 在C+中有转义作用,要表示路径中的“”,应该再加上 一个“”,即写成“C:CPPtest.txt”。,文件处理,(2)关闭文件,对于程序不再使用的文件应该及时关闭,可调用close( ) 函数,格式如下: myoutfile.close( );,ios类把打开方式作为枚举常量进行了定义,
20、见表10-4。,文件处理,文件处理,3.文本文件读写 对文本文件的操作,一般有两种方法,一是用标准 流运算符(和),二是用文件流的put( )、get( ) 、getline( )、read( )、write( )等成员函数,来实现输 入输出操作 。 下面看几个例子。,【例10.11】 用插入与提取符进行文本文件的读写操作。,#include #include #include using namespace std; void main() ofstream myoutfile; myoutfile.open(“xie.txt”); if(!myoutfile) cout“xie.txt c
21、ant open !n“; abort(); ,char ch=A; while(chch) coutch; coutendl; myinfile.close(); ,文件处理,程序分析:程序先把26个大写字母写入文本文件xie.txt中,然 后将该文件的内容逐字符读取到内存中,之后送到显示器上显 示。其中myoutfile.open(“xie.txt”)并没有指定打开方式, C+规定:对ofstream默认为ios:out,ifstream默认为 ios:in。但对fstream就必须明确指出打开方式。 程序中还对打开文件成功与否进了判断,这点很重要。如果 文件打开失败,自然不能往文件写入数
22、据,否则会出现严重错 误!程序中的abort( )函数即为退出程序的函数,该函数在头文 件stdlib.h中说明。,【例10.12】 用put( )与get( )函数进行文本文件的读写操作。,#include #include #include #include using namespace std; void main() fstream myoutfile,myinfile; myoutfile.open(“xie.txt“,ios:out); char str=“Example of file operation.“; for(int i=0;i=strlen(str);i+),myo
23、utfile.put(stri); myoutfile.close(); myinfile.open(“xie.txt“,ios:in); char ch; while(myinfile.get(ch) coutch; coutendl; myinfile.close(); ,【例10.13】 用getline( )函数按行读取文本文件的内容。,#include #include using namespace std; void browseFile(char *fileName); void main() char fname60; coutfname; browseFile(fname)
24、; ,void browseFile(char *fileName) ifstream infile(fileName,ios:in); char s80; while(!infile.eof() infile.getline(s,80); coutsendl; infile.close(); ,比较get()与getlina()的区别。,【例10.14】 复制文本文件。,#include #include using namespace std; int copyFile(char *srcFile,char *desFile); void main() char sfname60,dfna
25、me60; coutsfnamedfname; copyFile(sfname,dfname); int copyFile(char *srcFile,char *desFile) char ch;,ifstream infile(srcFile,ios:in); ofstream outfile(desFile,ios:out); if(!infile) cerrsrcFile“ :File open error!n“; return 0; if(!outfile) cerrdesFile“ :File open error!n“; return 0; while(infile.get(ch
26、) outfile.put(ch); cout“.Finish!.n“; return 1;,文件处理,4.二进制文件的读写 对二进制文件的读写操作,主要用istream类的成 员函数read和write来实现。函数的原型为: istream:read(char *buffer,int len); ostream:write(const char *buffer,int len); 其中:字符指针buffer指向内存的一段空间,len 是要 读或写的字节数。,【例10.15】 用read和write函数实现二进制文件的读写,#include #include using namespace s
27、td; struct student int num; char name20; double score; ; Student data4=101,“Xietin“,90,102,“Hulin“,88,103,“Weiwei“,96,104,“Libai“,99; void main() fstream myoutfile,myinfile; myoutfile.open(“c:student.dat“,ios:out|ios:binary);,【例10.15】 用read和write函数实现二进制文件的读写,for(int i=0;i4;i+) myoutfile.write(char*)
28、 ,【例10.15】 用read和write函数实现二进制文件的读写,程序分析:先将4个学生的数据写入到文件“c:student.dat”, 然后依次读出到结构体变量temp中,并送屏幕显示。特别要注意: read和write函数的第1个参数都是字符指针,如果所要读写的数据 类型与之不相符,需要进行强制转换,如:(char*) 即:从第一个元素开始写,写入整个数组长度的字节数。,文件处理,5.随机文件的读写 C+的二进制文件是流式文件,系统利用文件指针 记录流的当前位置,允许对指针进行控制,使它按用 户的意图移动到需要的位置,以便在该位置进行读写 操作。C+是提供了定位文件指针的成员函数,以实
29、 现对文件的随机访问,见表10-5。,文件处理,文件处理,说明: 1)为了便于记忆,函数名中的g是get的缩写,p是put的缩写。对输入输出文件定位指针只有一个,但函数有两组,这两组函数功能完全一样; 2)流中的位置及偏移量都是以字节数为单位的long型; 3)参照位置的取值及含义见图103:,文件处理,例如:假设input是一个istream类对象,则: input.seekg(40); / input流的指针移到第40个字节处 input.seekg(20,ios:beg); /以流开始位置为基准,后移20个字节 input.seekg(-10,ios:cur); /以流当前位置为基准,前
30、移20个字节 input.seekg(-10,ios:end); /以流结尾位置为基准,前移20个字节 可以用tellg()函数获得当前指针的位置,它返回的是表示存储地址的长整形 值,如: input.seekg(0,ios:beg); streampos pos= input. tellg();/返回流开始位置的指针值 input.seekg(0,ios:end); pos= input. tellg(); /返回流末尾位置的指针值,【例10.16】 二进制随机文件的读写,把5个学生的信息存入文件,从中分别读出第1、3、5个学生的数据 并显示出来。将第3个学生的修改后保存到原来位置,最后再次
31、读出5 个学生信息并显示。,#include #include using namespace std; struct student int num; char name20; float score; ;,【例10.16】 二进制随机文件的读写,int main() int i; student stud5=1001,“Li“,85,1002,“Fun“,97.5,1004,“Wang“,54, 1006,“Tan“,76.5,1010,“ling“,96; fstream iofile(“c:stud.dat“,ios:in|ios:out|ios:binary|ios:trunc);
32、if(!iofile) /如果打开文件错误 cerr“open error!“endl; /提示错误 abort(); /终止程序 for(i=0;i5;i+) /依次写入5条记录 iofile.write(char *) /用数组存放读取的记录,【例10.16】 二进制随机文件的读写,for(i=0;i5;i=i+2) iofile.seekg(i*sizeof(studi),ios:beg); /以起始为基准按要求偏移 iofile.read(char *) /定位到第1条记录,【例10.16】 二进制随机文件的读写,for(i=0;i5;i+) /依次读取5条记录并输出 iofile.r
33、ead(char *) ,程序运行结果如下: 1001 Li 85 (第1条记录) 1003 Wang 54 (第3条记录) 1005 ling 96 (第5条记录) 1001 Li 85,1002 Fun 97.5 1012 Wu 60 (注意:第3条记录已经修改过了) 1004 Tan 76.5 1005 ling 96,字符串流,在程序设计中,有时会利用string对象或字符串作为与外设 交换数据的缓冲区,C+提供了一种字符串流的方式来实现这 种功能。字符串流是以内存中用户自定义的字符串(字符数组 )为输入输出对象的数据流,也称为内存流 。C+支持C和 C+两种风格的字符串流控制,对于C
34、引入ostrstream、 istrstream、strstream这三个类,它们在strstream.h头文件中声 明,对于C+引入ostringstream、istringstream、stringstream这三 个类 ,它们包含在sstream.h头文件中。,字符串流不是标准设备,需要通过构造函数创建对象。,【例10.17】 C+风格字符串流的数据提取,#include #include /注意此头文件的写法 #include using namespace std; void main() string myStr(“Multi result 100 * 0.6“); /建立字符串流
35、对象 string str1,str2,str3; double x,y; istringstream input(myStr); /建立输入字符串类字符串流对象并与字符串关联 inputstr1str2xstr3y; /通过input从myStr中提取数据 coutstr1“ “str2“ “xstr3y“=“x*yendl; ,运行结果: Multi result 100*0.6=60,【例10.18】 C+风格字符串流的数据提取,#include #include /注意与C+的sstream不同 using namespace std; void main() char *myStr=“Multi result 100 * 0.6“; /字符指针 char str110,str210,str310; /字符数组 double x,y; /注意:在C+中是istringstream istrstream input(myStr); /建立istrstream对象并与字符串关联 inputstr1str2xstr3y; /通过input从myStr中提取数据 coutstr1“ “str2“ “xstr3y“=“x*yendl; ,运行结果: Multi result 100*0.6=60,
链接地址:https://www.31doc.com/p-3417983.html