《C的输入输出流》PPT课件.ppt_第1页
《C的输入输出流》PPT课件.ppt_第2页
《C的输入输出流》PPT课件.ppt_第3页
《C的输入输出流》PPT课件.ppt_第4页
《C的输入输出流》PPT课件.ppt_第5页
已阅读5页,还剩49页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第七章C 的I O流类库 7 1C 为何建立自己的输入输出系统 C 除了完全支持C语言的输入输出系统外 还定义了一套面向对象的输入输出系统 为什么C 还要建立自己的输入输出系统呢 C语言的输入输出系统不支持用户自定义的对象 如 Structmy struct inti floatf char str s 对此结构类型 在C语言中下面的语句是不能接受的 printf my struct s 因为printf 函数只能识别系统预定义的类型 而没有办法对新的数据类型进行扩充 用C 的输入输出系统 就可以通过重载 运算符来解以上问题 C 的类机制允它建立一个可扩展的输入输出系统 它可以通过修改和扩展来加入用户自定义类型及相应操作 1 7 2C 的流及流类库 7 2 1C 的流输入输出是一种数据传递操作 它可以看作字符序列在主机与外部介质之间的流动 流 stream 为从源 或生产者 到目的 或消费者 的数据流的引用 流具有方向性 与输入设备 如键盘 相联系的流称为输入流 与输出设备 如屏幕 相联系的流称为输出流 与输入输出设备 如磁盘 相联系的流称为输入输出流 C 中包含几个预定义的流 标准输入流cin与标准输入设备相关联标准输出流cout与标准输出设备相关联非缓冲型标准出错流cerr与标准错误输出设备相关联 非缓冲方式 缓冲型的标准出错流clog与标准错误输出设备相关联 缓冲方式 在缺省情况下 指定的标准输出设备是显示终端 标准输入设备是键盘 在任何情况下 有时用户把标准输出设备定向为其它设备 指定的标准错误输出设备总是显示终端 cerr Theaveragecannotbecomputed n 2 7 2 2流类库 C 流类库是用继承方法建立起来的一个输入输出类库 它具有两个平行的基类 streambuf类 ios类 所有其它的流类都是从它们直接或间接地派生出来的 使用C 的流类库 程序中可能应包含的头文件 iostream hstrstream hfstream hiomanip h1 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 状态标志字状态标志存放在数据成员longx flags中 ios类public中定义了一个枚举 它的每个成员可以分别定义状标志字的一个位 每一位都称为一个状标志位 5 这个枚举定义如下 enum 0000000000000001skipws 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位 中的01相当于一个枚举值 例如x flags中放0 x0011或17即为0000000000010001相当于0 x0001与0 x0010之并skipws 0 x0001 0000000000000001dec 0 x0010 0000000000010000 x flags 0 x0011 0000000000010001 7 2 ios类中用于控制输入输出格式的成员函数函数原型功能longios setf longflags 设置状态标志flagslongios unsetf longflags 清除状态标志 并返回前标志longios flags 测试状态标志longios flags longflags 设置标志flags 并返回前标志intios width 返回当前的宽度设置值intios width intw 设置域宽w 返回以前的设置intios precision intp 设置小数位数p返回以前的小数位数charios fill 返回当前的填充字符charios fill charch 设置填充字符ch返回当前的填充字符 8 1 设置状态标志 设置状态标志 即是将某一状态标志位置 1 可使用setf 函数其一般的调用格式为 流对象 setf ios 状态标志 例7 1 includemain istreamcin 对象cin可不定义ostreamcout 对象cout可不定义cin setf ios shipws 键盘输入时跳过输入空白cout setf ios left 设置输出左对齐cout setf ios showpos ios sciengific 中间用运算符 分隔cout 567 567 89 endl 设置showpos使得每个正数前添加 号 设置sciengific使浮点数按科学表示法 指数形式 进行显示 输出结果 567 5 678900e02注意 要设置多项标志时 中间用或运算符 分隔 9 2 清除状态标志 清除某一状态标志 即是将某一状态标志位置 0 可使用unseft 函数 使用时的调用格式与setf 相同 3 取状态标志取一个状态标志 可使用flags 函数 flags 函数有不带参数与带参数两种形式 lingios flags 用于返回当前的状态标志字 lingios flags liogflag 返回当前的状态标志字后 再者将状态标志字设置成flag 参数 flags liogflag 函数与setf liogflags 函数的差别在于 setf 函数是在原有的基础上追加设定的 而flags 函数是用新设定覆盖以前的状态标志字 例7 2几个成员函数的使用方法 includevoidshowflags longf 输出状态标志字函数 longi for i 0 x8000 i i i 1 用右移方法使i中的值为 1 的位不断右移if i 10 接1例7 2 voidmain longf cout setf ios unitbuf ios skipws f cout flags 取当前状态标志字showflags f 显示状态标志字cout setf ios showpos ios scientific 追加状态标志位f cout flags showflags f cout unsetf ios scientific 从状态标志字中去掉sciengificf cout flags showflags f f cout flags ios oct 重新设置状态标志字showflags f 显示设置前的状态标志字f cout flags 取设置后的状态标志字showflags f 显示设置后的状态标志字 11 程序运行结果为 0010000000000001 1 0010110000000001 2 0010010000000001 3 0010010000000001 4 0000000000100000 5 4 设置域宽 域宽主要用来控制输出 在ios类中域宽存放在数据成员intx width中 设置域宽的成员函数有两个 其一般格式为 intios width 返回当的域宽值intios width intw 设置域宽 并返回原来的域宽 5 设置输出的精度精度用来控制浮点数的输出显示精度 在ios类中用数据成员intx precision来存放精度 设置精度的成员函数的一般格式为 intios precision intp 重新设置浮点数所需小数的位数 并返回设置前的位数 6 填充字符填充字符的作用是 当输出值不满域宽时用填充字符来填充 缺省情况下填充字符为空格 所以在使用填充字符函数时 必须与width 函数相配合 否则就没有意义 在ios类中用数据成员x fill来存放填充字符 填充字符的成员函数有两个 其一般形式为 charios fill 返回当的填充字符charios fill charch 用ch重新设置填充字符 并返回设置前的填充字符 12 例7 3 includevoidmain cout x width cout width endl cout x fill cout fill endl cout x precision cout precision endl cout 123 123 45678 endl cout n cout x width 10 x fill x precision 7 n cout width 10 cout precision 7 cout 123 123 45678 234 567 endl cout x width cout width endl cout x fill cout fill endl cout x precision cout precision endl cout n cout x width 10 x fill 13 接1例7 3 cout fill 14 程序运行结果如下 x width 0 x fill x precision 0123123 45678 x width 10 x fill x preciosion 7 123123 4568234 567x width 0 x fill x precision 7 x width 10 x fill x precision 4 123123 4568123 123 4568x width 0 x fill x precision 4 例7 4利用控制输入输出格式的成员函数建立对齐的数字表 include includevoidmain doublex cout precision 4 cout xsqrt x x 2 n n for x 1 0 x 20 0 x cout width 8 cout x cout width 8 cout sqrt x cout width 8 cout x x n 这程序建立了如下的表xsqrt x x 211121 4142431 73219421652 23612562 44953672 64584982 8284649381103 1623100113 3166121123 4641144133 6056169143 7417196153 873225164256174 1231289184 2426324194 3598361204 4721400 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 flush刷新一个输出流 仅用于输出 8 setbase intn 把转换基数设置为n n的值为0 8 10 或16 n的缺省值为 0 即以十进制形式输出 16 9 resetiosflags longf 关闭由参数f指定的格式标志 可用于输入或输出 10 setiosflags longf 设置由参数f指定的格式标志 可用于输入或输出 11 setfill intc c为填充字符 缺省时为空格 可用于输入或输出 12 setprecision intn 设置数据小数部分的位数 缺省时小数的位数为6 可用输入输出 13 setw intn 设置域宽为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 includevoidmain cout setw 10 123 567 endl cout 123 setiosflags ios scientific setw 20 123 456789 endl cout 123 setw 10 hex 123 endl cout 123 setw 10 oct 8 123 endl cout 123 setw 10 setbase 0 123 endl cout resetiosflags ios scientific setprecision 4 123 456789 endl cout setiosflags ios left setfill setw 8 123 endl cout resetiosflags ios left setfill setw 8 456 endl 19 程序运行结果为 1234567 1231 234567e 02 1237b 7b173 173123 123 4568 123 456 例7 6二次方表与二次方根表的程序的程序的另一个版本 include include includevoidmain doublex cout setprecision 4 cout xsqrt x x 2 n n for x 1 x 20 0 x cout setw 8 x cout setw 8 sqrt x cout setw 8 x x n 20 3 用户自定义的操纵符 C 除了提供此同预定义的操纵符外 也允许用户自定义操纵符 把程序中频繁使用的输入输出操作合并成一个操纵符 若为输出流定义操纵符函数 则定义形式如下 ostream 21 例7 7自定义的操纵符 include includeostream 程序运行结果如下 1237b 22 例7 8 include includeistream 以上程序中定义了一个操纵符函数input1 该函数要求输入一个十六进制数 程序运行后 屏幕上显示 Enternumberusinghexformat 提示用户输入一个十六进制数 23 7 4用户自定义类型的输入输出 用户自定义的类型数据的输入或输出 可以通过重载运算符 和 和 可以直接用来输入或输出类的对象 7 4 1重载输出运算符 定义输出运算符 重载函数的一般格式如下 ostream 函数中的一个参数是对ostream对象的引用 它可以是其它任何合法的标示符 但必须与return后面的标示符相同 第二个参数接受将被输出的对象 其中class name是类名 obj为该类的对象名 24 例7 9输出运算符 重载的例子 includeclasscoord public intx y coord x 0 y 0 coord intI intj x I y j ostream 程序运行结果如下 5 610 34 25 例7 10把重载输出运算符定义为类的友元函数 这样就可以访问类的私有成员 includeclasscoord intx y public coord x 0 y 0 coord inti intj x i y j friendostream 26 程序运行结果如下 5 610 34 7 4 2重载输入运算符 只是要把ostream换成istream 把 代替 第二个参数是一个引用 定义输入运算符 重载函数的一般格式如下 istream 27 接1例7 11 ostream 28 接2例7 11 voidmain three dobj 10 20 30 定义类three d的对象objcout obj 输出对象obj的各成员值 将原值覆盖cout obj 输出对象obj的成员值 新值 程序运行结果如下 10 20 30Enterx y zvalue 40506040 50 60 29 7 5文件的输入输出 C 把文件看作字符序列 即文件是由一个字符数据顺序组成的 根据数据的组织形式 文件可分为文本文件和二进制文件 文本文件又称ASCII文件 它的每个字节存放一个ASCII代码 代表一个字符 二进制文件则是把内存中的数据 按其在内存中的存储形式原样写到磁盘上存放 文件是一个字符流或二进制流 它把数据看作是一连串的字符 而不考虑记录的界限 它对文件的存取以字符为单位进行 我们把这种文件称为流式文件 在C 中 要进行文件的输入输出 必须首先创建一个流 然后将这个流与文件相关联 即打开文件 此时才能进行读写操作 完成后再关闭这个文件 这是C 中进行文件输入输出的基本过程 7 5 1文件的打开与关闭1 文件的打开为了执行文件的输入输出 C 提供了三个流类 名称基类功能ofstream由ostream派生用于文件的输出ifstream由istream派生用于文件的输入fstream由iostream派生用于文件的输入或输出 30 建立流的过程就是定义流类的对象 例如 ifstreamin ofstreamout fstreamboth 它们分别定义了输入流对象in 输出流对象out 输入输出流对象both Open 函数是上述三个流类的成员函数 其原型为 voidopen constunsignedchar intmode intaccess filebuf openprot 打开语句 流类的对象 open constunsignedchar intmode intaccess filebuf openprot 其中第一个参数是用来传递文件名的 第二个参数mode的值决定文件将如何被打开 它必须取下面的值中的一个 access的值决定文件的访问方式 31 ios app使输出追加到文件尾部ios ate查找文件尾ios in打开一个文件进行读操作ios nocreate文件不存在时 导致open 失败ios noreplace若文件存在 则open 失败ios out打开一个文件进行写操作ios trunc使同名文件被删除ios binary文件以二进制方式打开 缺省时为文本文件访问方式0普通文件1只读文件2隐含文件4系统文件8备份文件 32 打开文件的步骤 1 定义一个类的对象 例如 ofstreamout 2 使用open 函数打开文件 例如 out open test ios out 0 文件只有在打开后 才能对文件进行读写操作 由于某些原因 可能打开失败 因此使用文件之前必须进行执行检测 以确认打开一个文件是否成功 可以使用类似下面的方法进行检测 if mystream cout cannotopenfile n 错误处理代码 在实际编程时 打开一个文件的最常见的形式为 ofstreamout test 用if out 检测是否打开成功它相当于语句 ofstreamout out open test 2 文件的关闭关闭文件可使用close 函数完成 close函数也是流类中的成员函数 它不带参数 没有返回值 例如 out close 33 7 5 2文件的读写 在含有文件操作的程序中 必须有如下的预处理命令 include1 文本文件的读写文件打开后 文本文件的读写使用运算符 只是必须用与文件相连接的流代替cin和cout 例7 12把一个整数 一个浮点数和一个字符串写到磁盘文件test中 includeintmain ofstreamfout test if fout cout cannotopenoutputfile n return1 fout 10 123 456 Thisisatestfile n fout close return0 用 写字板 可以看到test文件的内容 10123 456 thisisatestfile 34 例7 13先建立一个输出文件 向它写入数据 然后关闭文件 再按输入模式打开它 并读取信息 includevoidmain ofstreamfout test2 if fout cout str i cout str i endl fin close 程序建立一个输出文件test2 并向它写入数据 关闭输出文件test2 再将文件test2按输入模式打开 并将字符串 hello n 读给字符数组str 将整数100读给整型变量i 最后在屏幕上显示出str和I的值 如下所示 Hello 100 35 例7 14从键盘读入字符串 并将它们写进磁盘文件 当用户输入空白字符时 程序停止 include includevoidmain intargc char argv if argc 2 cout n return1 ofstreamoutf argv 1 if outf cout cannotopenoutputfile n return1 charstr 60 cout Writestringstodisk RETURNtostop n do cout gets str outf str endl while str outf close 这个例子采用了命令行参数的形式 输入以下命令行 程序运行情况如下 Writestringstodisk RETURNtostop abcdefg 从键盘输入一个字符串 输入空行 程序停止 程序运行后 在磁盘上生成一个名为的文件 其内容 abcdefg 36 2 二进制文件的读写 任何文件 无论它包含格式化的文本还是包含原始数据 都能以文本方式或二进制方式打开 文本文件是字符流 而二进制文件是字节流 1 用get 函数和put 函数读写二进制文件get 是输入流类istream中定义的成员函数 它可以从与流对象连接的文件中读出数据 每次读出一个字节 字符 put 是输出流类ostream中的成员函数 它可以向与流对象连接的文件中写入数据 每次写入一个字节 字符 get 函数有许多格式 其最一般的使用版本的原型如下 istreamget 函数从相关流中只读一个字符 并把该值放如引用ch 中 put 函数的原型如下 ostream put charch put 函数将字符ch写入流中 37 例7 15实现任意类型的文件拷贝 include includevoidmain intargc char argv charch if argc 3 cout Badcommond n return0 ifstreaminf argv 1 if inf cout Cannotopensoucefile return1 ofstreamoutf argv 2 if outf cout Cannotopentargetfile return1 while inf inf get ch outf put ch inf close outf close 假定本程序的文件名为mvc7 15 cpp 经编译 连接后生成的可执行文件名为mvc7 15 exe 则在DOS下输入以下命令行 D mvc7 15file1 exefile2 exe该程序的执行结果 是把文件file1 exe中的信息拷贝到文件file2 exe中 38 eof 函数的使用 二进制文件的处理过程与文本文件的处理过程基本相同 但在判断文件是否结束时有所区别 在文本文件中 遇到文件结束符 get函数返回一个文件结束标志EOF 该标志的值为 1 但在处理二进制文件时 读入某一字节中的二进制数的值可能是 1 这与EOF的值相同 这样就有可能出现读入的有用数据被处理成 文件结束 的情况 为了解决这个问题 c 提供了一个成员函数eof 用来判断文件是否真的结束 其原型为 inteof 当到达文件末尾时 它返回一个非零值 否则返回零 当输入文件是键盘时 其结束符是ctrl z eof 函数返回的值为真 39 例7 16在屏幕上显示任何给定文件的内容 include includemain intargc char argv charch if argc 2 cout n return1 ifstreamin argv 1 if in cout Cannotopenfile return1 while in eof in get ch cout ch return0 假定本程序的文件名为mvc7 16 cpp 经编译 连接后生成的可执行文件名为mvc7 16 exe 则在DOS下输入以下命令行 D mvc7 16file1该程序的执行结果 是把文件file1中的信息在屏幕上显示 40 2 用read 函数和write 函数读写二进制文件 有时需要读写一组数据 如一个结构变量的值 为此C 提供了两个函数read 和write 用来读写一个数据块 read 函数 函数原型 istream read unsignedchar buf intnum read 是类istream中的成员函数 其功能为 从相应的流中读取num个字节 字符 并把它们放入指针buf所指的缓冲区中 调用格式 read 缓冲区首址 读入的字节数 注意 缓冲区首址 的数据类型为unsignedchar 当输入其它类型数据时 必须进行类型转换 例如 intarray 50 60 70 定义了一个整型数组array read unsignedchar array sizeof array 对整型数组array 为了把数据从文件读入到它中 必须在read 函数中把它转换为unsignedchar 类型 由sizeof 函数确定要读入的字节数 41 write 函数 函数原型 ostream write constunsignedchar buf intnum write 是流类ostream的成员函数 利用该函数 可以把buf所指的缓冲区num个字节写到相应的流上 参数的含义及调用注意事项与read 函数类似 注意 如果在num个字节被读出之前就达到了文件尾 则read 只是停止执行 此时缓冲区包含这些字符 我们可以用另一个成员函数gcount 统计出有多少字符被读出 gcount 的原型如下 intgcount 它返回所读取的字节数 42 例7 17用write 函数向文件test中写入双精度数与字符串 include include includemain ofstreamoutf test if out cout cannotopenoutputfile n return1 doublenum 100 45 charstr Thisisatest out write char 程序执行后 屏幕上不显示任何信息 但程序已将双精度100 45和字符串 thisisatest 以二进制形式写入文件test中 用下面的程序可以读取文件test中的数据 并在屏幕上显示出来 以验证前面的程序操作 43 例7 18用read 函数读取例7 17中程序所建立的文件 include include includemain ifstreamin test if in cout cannotopeninputfile n return1 doublenum charstr 80 in read char 程序运行结果为 100 45Thisisatest 44 3 文件的随机读写 前面介绍的文件操作都是按一定顺序进行读写的 因此称为顺序文件 C 在类istream及类ostream中定义了几个与在输出流中随机移动文件指针的成员函数 则可以在流内随机移动文件指针 从而可以对文件的任意数据进行随机读写 用函数seekg 和seekp 进行随机访问 函数seekg 用于输入文件 函数seekp 用于输出文件 45 它们的函数原型如下 istream其中 参数origin表示文件指针的起始位置 offset表示相对于这个起始位置的位移量 seek dir是一个系统定义的枚举名 origin是枚举变量 origin的取值有以下三种情况 ios beg从文件头开始 把文件指针移动由offset指定的距离 offset的值为正数 ios cur从当前位置开始 把文件指针向前 后 移动由offset指定的距离 offset的值为正或负数 正数时向前移 负数时向后移 ios end从文件尾开始 把文件指针移动由offset指定的距离 offset的值为负数进行文件的随机读写时 可以用以下函数测试文件指针的当前位置 streampostellg 用于输入文件 streampostellp 用于输出文件 streampos是在iostream h中定义的类型 实际上是long型的 46 例7 19演示seekp 函数 它修改文件中的指定字符 执行时在命令行指定文件名 其后跟想修改的字符的位置 然后再跟新的字符 include include includeintmain intargc char argv if argc 4

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论