c语言中有三个系统预定义的流,第七章C的输入输出流.ppt

5ee0ea45b5ada3405c55305d8e1ca595.gif第七章C的输入输出流.ppt

第七章 C的I/O流类库,,7.1 C为何建立自己的输入输出系统,C除了完全支持C 语言的输入输出系统外,还定义了一套面向对象的输入输出系统。为什么C 还要建立自己的输入输出系统呢C 语言的输入输出系统不支持用户自定义的对象,如 Struct my_struct int i; float f; char *str; s; 对此结构类型,在C语言中下面的语句是不能接受的 printf“my_struct”,s; 因为printf 函数只能识别系统预定义的类型,而没有办法对新的数据类型进行扩充.。用C的输入输出系统,就可以通过重载“”运算符来解以上问题。 C的类机制允它建立一个可扩展的输入输出系统,它可以通过修改和扩展来加入用户自定义类型及相应操作。,1,,7.2 C的流及流类库,7.2.1 C的流 输入输出是一种数据传递操作,它可以看作字符序列在主机与外部介质 之间的流动。 流stream为从源或生产者到目的或消费者的数据流的引用。 流具有方向性 与输入设备如键盘相联系的流称为输入流; 与输出设备如屏幕相联系的流称为输出流; 与输入输出设备如磁盘相联系的流称为输入输出流。 C中包 含几个预定义的流 标准输入流 cin 与标准输入设备相关联 标准输出流 cout 与标准输出设备相关联 非缓冲型标准出错流 cerr 与标准错误输出设备相关联非缓冲方式 缓冲型的标准出错流 clog 与标准错误输出设备相关联缓冲方式 在缺省情况下,指定的标准输出设备是显示终端,标准输入设备是键盘。 在任何情况下(有时用户 把标准输出设备定向为其它设备),指定的标准错误输出设备总是显示终端。 cerr“The average cannot be computed.n”;,2,,7.2.2 流类库,C流类库是用继承方法建立起来的一个输入输出类库。它具有两个平行的基类streambuf 类, ios 类。所有其它的流类都是从它们直接或间接地派生出来的。使用C的流类库,程序中可能应包含的头文件 iostream.h strstream.h fstream.h iomanip.h 1. streambuf 类,,,,,streambuf,filebuf,strstreambuf,conbuf,,,,,派生,3,,2. ios 类,,,ios,,fstreambase,,strstreambase,,ostream,,istream,,istrstream,,ofstream,,ostrstream,,constream,,ifstream,,fstream,,istream_withassign,,ostream_withassign,,iostream_withassign,,strstream,,iostream,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,7.3输入输出的格式控制,7.3.1 用ios 类的成员函数进行格式控制 ios类中有几个成员函数可以用来对输入输出进行格式控制。 主要控制 状态标志字、域 宽、填充字符及输出精度。 1. 状态标志字 状态标志存放在数据成员 long x_flags 中。ios 类 public 中定义了一个枚举,它的每个成员可以分别定义状标志字的一个位,每一位都称为一个状标志位。,5,,.,这个枚举 定义 如下 enum 0000 0000 0000 0001 skipws 0 x0001,跳过输入中的空白,可用于输入 left 0 x0002,左对齐输出,可用于输出 right 0 x0004,右对齐输出,可用于输出 internal 0 x0008,在符号位和基指示符后填入字符,可用于输出 dec 0 x0010,转换基数为十进制,可用于输入或输出 oct 0 x0020,转换基数为八进制,可用于输入或输出 hex 0 x0040,转换基数为十六进制,可用于输入或输出 showbase 0 x0080,在输出时显示基指示符,可于输入或输出 showpoint 0 x0100,在输出时显示小数点,可用于输出 uppercase 0 x0200,十六进制输出时,表示制式的和表示数值的字符一律为大写 ,可用于输出 showpos 0 x0400,正整数前显示””符号,可用于输出 scientific 0 x0800,用科学表示法显示浮点数,可用于输出 fixed 0 x1000,用定点形式显示浮点数,可用于输出 unitbuf 0 x2000,在输出操作后立即刷新所有流,可用于输出 stdio 0 x4000,在输出操作后刷新stdout 和stderr,可用于输出 ;,6,,,2,x_flags取以上枚举值的并存,即x_flags上的每一位长整数为16位中的0 1相当于一个枚举值。例如 x_flags 中放 0 x0011 或 17即为 0000 0000 0001 0001 相当于 0 x0001 与 0 x0010 之并 skipws0 x0001 0000 0000 0000 0001 dec 0 x0010 0000 0000 0001 0000 x_flags 0 x0011 0000 0000 0001 0001,,7,,2. ios类中用于控制输入输出格式的成员函数 函数原型 功能 long iossetflong flags; 设置状态标志flags long iosunsetflong flags; 清除状态标志,并返回前标志 long iosflags; 测试状态标志 long iosflagslong flags; 设置标志flags,并返回前标志 int ioswidth; 返回当前的宽度设置值 int ioswidthint w; 设置域宽w,返回以前的设置 int iosprecisionint p; 设置小数位数p返回以前的小数位数 char iosfill; 返回当前的填充字符 char iosfillchar ch; 设置填充字符ch返回当前的填充字符,,8,1设置状态标志,设置状态标志,即是将某一状态标志位置“1”,可使用setf函数 其一般的调用格式为流对象.setfios状态标志; 例7.1 include main istream cin; //对象cin可不定义 ostream cout; //对象cout可不定义 cin.setfiosshipws; //键盘输入时跳过输入空白 cout.setfiosleft; //设置输出左对齐 cout.setfiosshowpos | iossciengific;//中间用运算符 “|”分隔 cout567“ ” 567.89endl; 设置showpos使得每个正数前添加“”号, 设置sciengific使 浮点数按科学表示法 指数形式进行显示,输出结果 567 5.678900e02 注意要设置多项标志时,中间用或运算符 “|” 分隔。,9,,2清除状态标志,清除某一状态标志,即是将某一状态标志位置”0”,可使用unseft函数,使用时的调用格式与setf相同。 3取状态标志 取一个状态标志,可使用 flags函数。flags函数有不带参数与带 参数两 种形式 ling ios flags; 用于返回当前的状态 标志字; ling ios flags liog flag; 返回当前的状态 标志字后,再者将状态标志字设置成flag参数。 flagsliog flag函数与setfliog flags函数的差别在于setf函数是在原有的基础上追加设定的,而flags函数是用 新设定覆盖以前的状态标志字。 例 7.2 几个成员函数的使用 方法 include void showflagslong f //输出状态标志字函数 long i; fori0 x8000;i;ii1//用右移方法使i中的值为”1”的位不断右移 if i ,10,,接1 例 7.2,void main long f; cout.setfiosunitbuf|iosskipws; fcout.flags; //取当前状态标志字 showflagsf; //显示状态标志字 cout.setfiosshowpos|iosscientific; //追加状态 标志位 fcout.flags; showflagsf; cout.unsetfiosscientific; //从状态标志字中去掉sciengific fcout.flags; showflagsf; fcout.flagsiosoct; //重新设置状态标志字 showflagsf; //显示设置前的状态标志字 fcout.flags; //取设置 后的状态标志字 showflagsf; //显示设置后的状态标志字 ,11,,,程序运行结果为; 0010000000000001 1 0010110000000001 2 0010010000000001 3 0010010000000001 4 0000000000100000 5,4设置域宽,域宽主要用来控制输出,在ios 类中域 宽存放在数据成员int x_width中,设置域宽的成员函数有两个,其一般格式为 int ios width; 返回当的域宽值 int ios widthint w; 设置域宽,并返回原来的域 宽 5设置输出的精度 精度用来控制浮点数的输出显示精度,在ios类中用数据成员int x_precision来存放精度,设置精度的成员函数的一般格式为 int iosprecisionint p; 重新设置浮点数所需小数的位数,并返回设置前的位数 6填充字符 填充字符的作用是当输出值不满域宽时用填充字符来填充,缺省情况下填充字符为空格,所以在使用填充字符函数时,必须与width函数相配合,否则就没有意义,在ios类中用数据成员x_fill来存放填充字符。填充字符的成员函数有两个,其一般形式为 char ios fill; 返回当的填充字符 char ios fillchar ch; 用ch重新设置填充字符,并返回设置前的填充字符。,12,,例 7.3,include void main cout”x_width”cout.widthendl; cout”x_fill”cout.fillendl; cout”x_precision”cout.precisionendl; cout123” “123.45678endl; cout”---------------------------------------n”; cout”****x_width10,x_fill ,x_precision7****n”; cout.width10; cout.precision7; cout123 ” “123.45678” “234.567endl; cout ”x_width”cout.widthendl; cout”x_fill”cout.fillendl; cout”x_precision”cout.precisionendl; cout”---------------------------------------n”; cout”****x_width10,x_fill,13,,接1 例 7.3,cout.fill ,14,,,程序运行结果如下 x_width0 x_fill x_precision0 123 123.45678 ------------------------------------- ****x_width10,x_fill ,x_preciosion7**** 123 123.4568 234.567 x_width0 x_fill x_precision7 ------------------------------------- ****x_width10,x_fill cout.precision4; cout” x sqrtx x2nn”; forx1.0;x20.0;x cout.width8; coutx ; cout.width8; coutsqrtx ; cout.width8; coutx*xn; ,这程序建立了如下的表 x sqrtx x2 1 1 1 2 1.4142 4 3 1.7321 9 4 2 16 5 2.2361 25 6 2.4495 36 7 2.6458 49 8 2.8284 64 9 3 81 10 3.1623 100 11 3.3166 121 12 3.4641 144 13 3.6056 169 14 3.7417 196 15 3.873 225 16 4 256 17 4.1231 289 18 4.2426 324 19 4.3598 361 20 4.4721 400,15,,,7.3.2使用操作符进行输入输出格式控制,C提供了另一种进行I/O格式控制的方法,这一方法使用了一种称为操纵符也称为操纵函数的特殊函数。在很多情况下,使用操纵符进行格式化控制比用ios格式标志和成员函数要方便。 1. C预定义的操纵符 C预定义的操纵符是以一个流引用作为其参数,并返回同一流的引用,因此它可以嵌入到输入输出操作的链中。操纵符可用来改变域宽,使整型数以八进制或十六进制形式输入或输出,并设置填充字符等。许多操纵符的功能类似于上面介绍的ios类成员函数的功能。C提供的预定义操纵符如下 1 dec 以十进制形式输入或输出整型数,可用于输入或输出 。 2 hex 以十六进制形式输入或输出整型数,可用于输入或输出。 3 oct 以八进制形式输入或输出整型数,可用于输入或输出。 4 ws 用于在输入时跳过开头的空白符,仅用于输入。 5 endl 插入一个换行符并刷新输出流,仅用于输出。 6 ends 插入一个空字符,通常用来结束一个字符串,仅用于输出。 7 刷新一个输出流,仅用于输出。 8 setbase int n 把转换基数设置为nn的值为0,8,10,或16,n的缺省值为”0”,即以十进制形式输出。,16,, 9 resetiosflags long f 关闭由参数 f 指定的格式标志,可用于输入或输出。 10 setiosflags long f 设置由参数 f 指定的格式标志,可用于输入或输出。 11 setfill int c c 为填充字符,缺省时为空格,可用于输入或输出。 12 setprecision int n 设置数据小数部分的位数,缺省时小数的位数为6,可用输入输出。 13 setw int n 设置域宽为n,可用于输入或输出。,,17,操纵符setiosflags 和resetiosflags 中所用的格式标志,格式标志名 含 义 ios left 输出数据按域宽左对齐输出 ios right 输出数据按域宽右对齐输出 ios scientific 使用科学计数法表示浮点数 ios fixed 使用定点形式表示浮点数 ios dec 转换基数为十进制形式 ios hex 转换基数为十六进制形式 ios oct 转换基数为八进制形式 ios uppercase 十六进制形式和科学计数法输出时,表示数值的字 符 一律为大写 ios showbase 输出带有一个表示制式的字符如”X”表示十六进 制,”O”表示八进制 ios showpos 在正数前添加一个””号 ios showpoint 浮点输出时必须带有一个小数点 2.操纵符的使用 操纵符分为带参数的操纵符和不带参数的操纵符.通常,不带参数的操纵符在iostream.h 文件中定义,带参数的操纵符在 iomanip.h 文件中定义。,,,,,18,,例7. 5 使用操纵符的输入输出格式控制,include include void main cout setw 10123567endl; // cout123setiosflagsiosscientificsetw20123.456789endl; // cout 123setw10hex123endl; // cout 123setw10oct8123endl; // cout 123setw10setbase0123endl; // coutresetiosflagsiosscientificsetprecision4123.456789endl; coutsetiosflagsiosleftsetfillsetw8123endl; // coutresetiosflagsiosleftsetfillsetw8456endl; // ,19,,,程序运行结果为 1234567 123 1.234567e02 123 7b 7b 173 173 123 123.4568 123 456 ,例7.6 二次方表与二次方根表的程序的程序的另一个版本,include include include void main double x; coutsetprecision 4; cout “ x sqrt x x2nn”; for x1.;x20.0;x; cout setw8x ; cout setw8sqrtx ; cout setw8x*xn; ,20,,,3. 用户自定义的操纵符,C除了提供此同预定义的操纵符外,也允许用户自定义操纵符,把程序中频繁使用的输入输出操作合并成一个操纵符。 若为输出流定义操纵符函数,则定义形式如下 ostream ,21,,例 7.7 自定义的操纵符,include include ostream 程序运行结果如下 123 7b coord x0; y0; coord int I,int j xI; yj; ; ostream 程序运行结果如下 5,6 10,34,25,,,例 7.10 把重载输出运算符定义为类的友元函数,这样就可以访问类的私有成员,include class coord int x,y; public coord x0; y0; coord int i,int j xi; yj; friend ostream ,26,,,程序运行结果如下 5,6 10,34,7.4.2 重载输入运算符 “”,只是要把ostream换成istream ,把””代替,第二个参数是一个引用。 定义输入运算符””重载函数的一般格式如下 istream ,27,,接1 例 7.11,ostream ,28,,,接2 例 7.11,void main three_d obj 10,20,30; //定义类three_d的对象obj coutobj; //输出对象obj的各成员值,将原值覆盖 coutobj; //输出对象obj的成员值新值 ,程序运行结果如下 10,20,30 Enter x,y,z value 40 50 60 40,50,60,,29,7.5文件的输入输出,C把文件看作字符序列,即文件是由一个字符数据顺序组成的。根据数据的组织形式,文件可分为文本文件和二进制文件。文本文件又称ASCII文件,它的每个字节存放一个ASCII代码,代表一个字符。二进制文件则是把内存中的数据,按其在内存中的存储形式原样写到磁盘上存放。文件是一个字符流或二进制流,它把数据看作是一连串的字符,而不考虑记录的界限,它对文件的 存取以字符为单位进行。我们把这种文件称为流式文件。在C中,要进行文件的输入输出,必须首先创建一个流,然后将这个流与文件相关联,即打开文件,此时才能进行读写操作,完成后再关闭这个文件。这是C中进行文件输入输出的基本过程。 7.5.1 文件的打开与关闭 1. 文件的打开 为了执行文件的输入输出,C提供了三个流类。 名 称 基 类 功 能 ofstream 由ostream 派生 用于文件的输出 ifstream 由istream 派生 用于文件的输入 fstream 由iostream 派生 用于文件的输入或输出,,,,,,30,,建立流的过程就是定义流类的对象,例如,ifstream in; ofstream out; fstream both; 它们分别定义了输入流对象in,输出流对象out,输入输出流对象both。 Open 函数是上述三个流类的成员函数,其原型为 void openconst unsigned char *,int mode , int accessfilebufopenprot; 打开语句 流类的对象. openconst unsigned char *,int mode ,int accessfilebufopenprot; 其中第一个参数是用来传递文件名的;第二个参数mode的值决定文件将如何被打开,它必须取下面的值中的一个;access的值决定文件的访问方式。,31,,iosapp 使输出追加到文件尾部 iosate 查找文件尾 iosin 打开一个文件进行读操作 iosnocreate 文件不存在时,导致open 失败 iosnoreplace 若文件存在,则open 失败 iosout 打开一个文件进行写操作 iostrunc 使同名文件被删除 iosbinary 文件以二进制方式打开,缺省时为文本文件 访问方式 0 普通文件 1 只读文件 2 隐含文件 4 系统文件 8 备份文件,,32,打开文件的步骤,1 定义一个类的对象,例如 ofstream out; 2 使用open 函数打开文件。例如out.open”test”,iosout ,0; 文件只有在打开后,才能对文件进行读写操作。由于某些原因,可能打开失败,因此使用文件之前必须进行执行检测,以确认打开一个文件是否成功。可以使用类似下面的方法进行检测 if( mystream) cout”cannot open file n”; //错误处理代码 在实际编程时,打开一个文件的最常见的形式为 ofstream out ”test” ; 用 if out 检测是否打开成功 它相当于语句 ofstream out; out.open”test”; 2. 文件的关闭 关闭文件可使用close 函数完成,close函数也是流类中的成员函数,它不带参数,没有返回值,例如 out.close ;,33,,7.5.2 文件的读写,在含有文件操作的程序中,必须有如下的预处理命令 include 1. 文本文件的读写 文件打开后,文本文件的读写使用运算符“”,只是必须用与文件相连接的流代替cin和cout。 例 7.12 把一个整数、一个浮点数和一个字符串写到磁盘文件test中。 include int main ofstream fout(”test”); if (fout) cout”cannot open output file n”; return 1; fout10” ”123.456” ”This is a test file.”n”; fout.close(); return 0; 用“写字板”可以看到test文件的内容10 123.456 “this is a test file”,34,,,例 7.13 先建立一个输出文件,向它写入数据,然后关闭文件,再按输入模式打开它,并读取信息。, include void main ofstream fout(”test2”); if(fout) coutstri; coutstr” ”iendl; fin.close(); ,程序建立一个输出文件test2,并向它写入数据,关闭输出文件test2。再将文件test2按输入模式打开,并将字符串“hellon”读给字符数组str,将整数100读给整型变量i。最后在屏幕上显示出str和I的值,如下所示 Hello 100,35,,,例 7.14 从键盘读入字符串,并将它们写进磁盘文件。当用户输入空白字符时,程序停止。, include include void main(int argc,char *argv) if(argc2) coutn”; return 1; ofstream outf argv1; if outf cout”cannot open output file .n”; return 1; char str60; cout”Write strings to disk, RETURN to stopn”; do cout””; getsstr; outfstrendl; while *str; outf.close ; ,这个例子采用了命令行参数的形式,输入以下命令行 程序运行情况如下 Write strings to disk,RETURN to stop abcdefg (从键盘输入一个字符串) (输入空行,程序停止) 程序运行后,在磁盘上生成一个名为的文件,其内容 abcdefg,36,,,2. 二进制文件的读写,任何文件,无论它包含格式化的文本还是包含原始数据,都能以文本方式或二进制方式打开。文本文件是字符流,而二进制文件是字节流。 1 用get 函数和put 函数读写二进制文件 get 是输入流类istream中定义的成员函数,它可以从与流对象连接的文件中读出数据,每次读出一个字节字符。put 是输出流类ostream中的成员函数,它可以向与流对象连接的文件中写入数据,每次写入一个字节(字符)。 get 函数有许多格式,其最一般的使用版本的原型如下 istream get 函数从相关流中只读一个字符,并把该值放如引用ch if argc3 cout”Bad commond n”; return 0; ifstream inf argv1; if inf cout”Cannot open souce file.”; return 1; ofstream outf argv2; if outf cout”Cannot open target file.”; return 1; while inf inf.get ch; outf.put ch; inf.close ; outf.close ; ,假定本程序的文件名为mvc7_15.cpp,经编译、连接后生成的可执行文件名为mvc7_15.,则在DOS下输入以下命令行 D mvc7_15 file1. file2. 该程序的执行结果,是把文件file1.中的信息拷贝到文件file2.中,38,,,eof 函数的使用,二进制文件的处理过程与文本文件的处理过程基本相同,但在判断文件是否结束时有所区别。在文本文件中,遇到文件结束符,get函数返回一个文件结束标志EOF,该标志的值为-1。但在处理二进制文件时,读入某一字节中的二进制数的值可能是-1,这与EOF的值相同。这样就有可能出现读入的有用数据被处理成“文件结束”的情况。为了解决这个问题,c提供了一个成员函数eof,用来判断文件是否真的结束,其原型为 int eof(); 当到达文件末尾时,它返回一个非零值,否则返回零。当输入文件是键盘时,其结束符是ctrl_z, eof 函数返回的值为真。,39,,例 7.16在屏幕上显示任何给定文件的内容。, include include main int argc, char *argv char ch; if argc2 coutn”; return 1; ifstream in argv1; if in cout”Cannot open file”; return 1; while in.eof in.get ch; coutch; return 0; ,假定本程序的文件名为mvc7_16.cpp,经编译、连接后生成的可执行文件名为mvc7_16.,则在DOS下输入以下命令行 D mvc7_16 file1 该程序的执行结果,是把文件 file1 中的信息在屏幕上显示。,40,,,2 用read 函数和write 函数读写二进制文件,有时需要读写一组数据 如一个结构变量的值,为此C提供了两个函数read 和write ,用来读写一个数据块。 read 函数 函数原型 istream return 1; double num100.45; char str ”This is a test”; out.write char * 程序执

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值