欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > PPT文档下载  

    程序设计实习第十八讲输入输出流和文件操作.ppt

    • 资源ID:6004953       资源大小:299.04KB        全文页数:64页
    • 资源格式: PPT        下载积分:10金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要10金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    程序设计实习第十八讲输入输出流和文件操作.ppt

    程序设计实习第十八讲 输入输出流和文件操作,主讲教师:田永鸿http:/,2,上节内容回顾,虚函数和多态纯虚函数和抽象类多态的实现:虚函数表虚函数的访问权限构造函数和析构函数中调用虚函数虚析构函数,3,课堂问题(1),判断对错并说明理由抽象基类中的所有virtual函数都必须声明为纯virtual函数;声明某个类为virtual,该类就成为抽象类。如果基类声明了一个纯virtual函数,派生类只有实现该函数才能成为具体类。下面的定义是否正确,该如何改正?class base string name()return basename;virtual void print(ostream,class derived:public base void print()base:print(os);os“”mem;private:int meme;同时,基类及派生类也应该定义构造函数和析构函数。base:base(string name):basename(name);base:base();derived:derived(string name,int val):base(name),mem(val);derived:derived();,4,课堂问题(2),下列关于重载函数和虚函数的辨析描述中,理解不正确的是:重载函数处理的是同一类层次上的同名函数问题,而虚函数处理的是不同派生层次上的同名函数问题。重载函数要求函数有相同的函数名称,不管返回值类型是否相同,但参数序列必须不同,而虚函数则要求函数名、参数序列和返回值类型完全相同。重载函数和虚函数都必须是类成员函数,但重载函数一般功能类似,而虚函数一般功能有所不同,甚至基类虚函数的函数体可以为空,具体功能在派生类中添加。重载函数在编译时,根据传递参数序列的不同,确定具体调用表现多态性,而虚函数在运行时,根据基类指针或引用所指向对象的不同,确定具体调用表现出多态性。,5,课堂问题(3),请写出运行时输出的结果 class A public:A()virtual void func()cout A:func endl;A()virtual void fund()cout A:fund endl;class B:public A public:B()func();void fun()func();B()fund();,class C:public B public:C()void func()cout C:func endl;C()fund();void fund()cout C:fund endl;main()C c;,A:funcC:fundA:fund,6,内容提要,输入输出流文件操作作业,7,输入输出流,流的概念模型C+中与流操作相关的类及其继承关系输入输出流对象:cin,cout,cerr,clog输出流输入流无格式输入输出流操纵算子流格式状态,8,流的概念模型,流-可以看作一个无限长的二进制数字序列通过读写指针进行流的读和写(以字节为单位),将流上的数据读进变量x,将y的值写入流,y,x,9,流的概念模型,输出流 可以看作一端无限,另一端通过写指针不停地向后写入新内容的单向流,,写指针,10,流的概念模型,输入流 可以看作一端无限,另一端通过读指针不停地从流中读取新内容的单向流,读出的内容从流中删去。,读指针,11,有格式读写和无格式读写,有格式读写,以某种数据类型为单位读写例如:读一个整数,写一个浮点数等;无格式读写,以字节为单位读写,不区分其中的内容例如:读20个字节,写50个字节等;,12,缓冲区刷新,向输出流中写数据时,通常是先向缓冲区中写,当缓冲区写满时,才真正向输出流写也可以通过函数在程序中主动将缓冲区内容写入输出流。,13,C+中与流操作相关的类及其继承关系,ios,istream,ostream,ifstream,iostream,ofstream,fstream,14,标准流对象,输入流对象cin 与标准输入设备相连输出流对象:cout 与标准输出设备相连 cerr 与标准错误输出设备相连,非缓冲输出 clog 与标准错误输出设备相连,缓冲输出,15,输出流,流插入运算符 cout“Good morning!n”;不刷新缓冲区 cout“Good”;不刷新缓冲区 cout“morning!”;不刷新缓冲区 cout endl;刷新缓冲区 cout flush;刷新缓冲区cout显示内容的时候会先将欲显示内容存放在缓存区,待刷新的时候才将内容付显,而具有刷新功能的语句为endl或者flush。,16,输出流,输出表达式 cout(47+53);/将表达式括起来,/避免优先级冲突。连续使用流插入运算符 cout“ha ha”(100+100)endl;相当于(cout“ha ha”)(100+100)endl;,17,输出流,输出 char*类型的变量 char*string=“test”;cout(string);/输出 string的地址/0 x0042501c-会变的!,用法:static_cast(a)将地址a转换成类型T,T和a必须是指针、引用、算术类型或枚举类型。表达式static_cast(a),a的值转换为模板中指定的类型T。在运行时转换过程中,不进行类型检查来确保转换的安全性。,18,输出流,用成员函数put输出字符 cout.put(A);put的连续使用 cout.put(A).put(a);,19,输入流,读取运算符 int x,y;cin x;cin y;或者 cin x y;,20,输入流,读取运算的返回值重载运算符的定义:istream while(cinx),21,输入流,成员函数 cin.get()读入一个字符(包括空白字符),返回该字符;char*cin.get(char*buffer,int size,char delim=n)或者读size 1 个字符入buffer,或者遇到n;在buffer最后加0,分隔符留在输入流.char*cin.getline(char*buffer,int size,char delim=n)或者读size 1 个字符入buffer,或者遇到n;在buffer最后加0,分隔符从流去掉.bool cin.eof()返回输入是否结束标志.,22,输入流,cin.peek():返回下一个字符,但不从流中去掉.cin.putback(char ch):将字符ch放回输入流cin.gcount():返回上次读入的字节数cin.ignore(int nCount=1,int delim=EOF):从流中删掉最多nCount个字符,遇到EOF时结束。,23,无格式输入输出,用read,write 进行指定字节数的输入输出const int SIZE=80;char bufferSIZE;cin.read(buffer,20);/cin.get(buffer,20);cout.write(buffer,cin.gcount();/gcount返回上次读入的字节数cout endl;输入:Using the read,write and gcount member functions 输出:Using the read,write,24,流操纵算子,整数流的基数:流操纵算子dec,oct,hex,setbase浮点数的精度(precision,setprecision)设置域宽(setw,width)用户自定义的流操纵算子,25,流操纵算子,整数流的基数:流操纵算子dec,oct,hex int n=10;cout n endl;cout hex n“n”dec n“n”oct n endl;输出结果:10 a 10 12,26,流操纵算子,浮点数的精度(precision,setprecision)precision是成员函数,其调用方式为:cin.precision(5);setprecision 是流操作算子,其调用方式为:cin setprecision(5);/可以连续输出它们的功能相同。,27,流操纵算子,流格式操纵算子setioflags setiosflags(ios:fixed)用定点方式表示实数seiosflags(ios:scientific)用指数方式表示实数setiosflags(ios:fixed)与seiosflags(ios:scientific)都可以和setprecision(n)合用,其效果分别为:控制小数点右边的数字个数,控制指数表示法的小数位数。在用浮点表示的输出中,setprecision(n)表示有效位数。在用定点表示的输出中,setprecision(n)表示小数位数。在用指数形式输出时,setprecision(n)表示小数位数。小数位数截短显示时,进行4舍5入处理。左右对齐输出可用setiosflags(ios:left)和setiosflags(ios:right)实现。强制显示小数点和符号可用setiosflags(ios:showpoint)和setiosflags(ios:showpos)实现。,28,流操纵算子,浮点数的精度(precision,setprecision)double x=12.3456789,y=12.34;cout setiosflags(ios:fixed)setprecision(6)x endl y endl;输出为:12.345679/小数点后有6位 12.340000,29,流操纵算子,浮点数的精度(precision,setprecision)double x=12.3456789,y=12.34;long z=1234567cout setprecision(6)x endl y endl z endl;输出为:12.3457/一共有6位 12.34/不到6位 1.23457e+006/科学计数法,30,流操纵算子,设置域宽(setw,width)两者功能相同,一个是成员函数,另一个是流操作算子,调用方式不同:cin setw(5);或者 cin.width(5);cout setw(5);或者 cout.width(5);不含参数的width函数将输出当前域宽,31,流操纵算子,设置域宽(setw,width)例:int w=4;输入:1234567890 char string10;输出:1234 cin.width(5);5678 while(cin string)90 cout.width(w+);cout string endl;cin.width(5);输入操作提取字符串的最大宽度比定义的域宽小1,这是因为在输入的字符串后面必须加上一个空字符。,32,流操纵算子,设置域宽(setw,width)例:int w=4;输入:happy new year char string10;输出?cin.width(5);while(cin string)cout.width(w+);cout string endl;cin.width(5);。,happ y new year,33,流操纵算子,设置域宽(setw,width)需要注意的是在每次读入和输出之前都要设置宽度。例如:char str10;输入:1234567890 cin.width(5);输出:1234 cin string;567890 cout string;cout string endl;,34,流操纵算子,设置域宽(setw,width)需要注意的是在每次读入和输出之前都要设置宽度。例如:char str10;输入:1234567890 cin.width(5);输出:1234 cin string;5678 cout string;cout string endl;(输出具有同样的性质),35,流操纵算子,用户自定义的流操纵算子ostream 输出:aa bb,36,流的错误状态,当流中发生格式错误时,设置failbit当发生导致数据丢失错误时,设置badbit如果eofbit、failbit、badbit都没有设置,则设置goodbit成员函数rdstate返回流的错误状态。成员函数clear把一个流的状态恢复为“好”,如:cin.clear(),清除cin,并为流设置goodbit。eof():判断流是否到文件尾,37,流格式状态,自己阅读 V2版的11.7(V5版的15.7),学会设置流格式状态,38,内容提要,输入输出流文件操作作业,39,文件操作,数据的层次文件和流建立顺序文件文件的读写指针有格式读写无格式读写,40,数据的层次,位 bit字节 byte域/记录 Field/Record例如:学生记录 int ID;char name10;int age;int rank10;我们将所有记录顺序地写入一个文件,称为顺序文件。,41,文件和流,可以将顺序文件看作一个有限字符构成的顺序字符流,然后象对cin,cout 一样的读写。回顾一下输入输出流类的结构层次:,ios,istream,ostream,ifstream,iostream,ofstream,fstream,42,建立顺序文件,#include/包含头文件ofstream outFile(“clients.dat”,ios:out|ios:binary);/打开文件ofstream 是 fstream中定义的类outFile 是我们定义的ofstream类的对象“clients.dat”是将要建立的文件的文件名ios:out 是打开并建立文件的选项ios:out 输出到文件,删除原有内容ios:app 输出到文件,保留原有内容,总是在尾部添加ios:ate 输出到文件,保留原有内容,可以在文件任意位置添加 ios:binary 以二进制文件格式打开文件,43,建立顺序文件,也可以先创建ofstream对象,再用 open函数打开 ofstream fout;fout.open(test.out,ios:out|ios:binary);判断打开是否成功:if(!fout)cerr“File open error!”endl;,44,文件的读写指针,对于输入文件,有一个读指针;对于输出文件,有一个写指针;对于输入输出文件,有一个读写指针;标识文件操作的当前位置,该指针在哪里,读写操作就在哪里进行。,45,文件的读写指针,ofstream fout(“a1.out”,ios:ate);long location=fout.tellp();/取得写指针的位置location=10L;fout.seekp(location);/将写指针移动到第10个字节处fout.seekp(location,ios:beg);/从头数locationfout.seekp(location,ios:cur);/从当前位置数locationfout.seekp(location,ios:end);/从尾部数locationlocation 可以为负值,46,文件的读写指针,ifstream fin(“a1.in”,ios:ate);long location=fin.tellg();/取得读指针的位置location=10L;fin.seekg(location);/将读指针移动到第10个字节处fin.seekg(location,ios:beg);/从头数locationfin.seekg(location,ios:cur);/从当前位置数locationfin.seekg(location,ios:end);/从尾部数locationlocation 可以为负值,47,字符文件读写,int x,y;/有类型的读写fin x y;fout x“y endl;说明:字符文件的读写本质是将所有类型转为字符串,再将字符串转成各种类型的数据。所以写出来的是文本格式的文件,可以在记事本中阅读。因为文件流也是流,所以前面讲过的流的成员函数和流操作算子也同样适用于文件流。,48,二进制文件读写,int x=10;fout.seekp(20,ios:beg);fout.write(reinterpret_cast(二进制文件读写,直接写二进制数据,记事本看未必正确。,reinterpret_cast(a)任何指针都可以转换成其它类型的指针,T必须是一个指针、引用、算术类型、指向函数的指针或指向一个类成员的指针。表达式reinterpret_cast(a)能够用于诸如char*到int*。,49,显式关闭文件,ifstream fin(“test.dat”,ios:in);fin.close();ofstream fout(“test.dat”,ios:out);fout.close();,50,获得文件长度,ofstream fout(1.txt,ios:out);char a100000;fout.write(reinterpret_cast(a),100000);fout.close();ifstream fin(1.txt,ios:in);fin.read(reinterpret_cast(a),100000);fin.seekg(0,ios:end);long b=fin.tellg();cout b endl;fin.close();,51,命令行参数,启动程序运行时可以指定命令行参数方式一开始-运行-输入cmd,按确定-dos窗口可以用 cd 切换当前目录:.cd 子目录 等等来到程序所在目录,启动程序:myprogram arg1 arg2或者在任意目录下,启动程序:e:/me/aa arg1 arg2绝对路径和相对路经的概念方式二在vc编程环境中:project-settings-debug-program arguments,52,命令行参数,int main(int argc,char*argv)cout argc endl;for(int i=0;iargc;i+)cout argvi endl;第一个参数为命令本身,第二个以后为参数,53,文件目录操作,dir-列文件及子目录cd-当前目录转换mkdir-创建目录.目录-当前目录.目录-父目录,54,在程序中得到某个路径下的文件,#include HANDLE f1;/句炳WIN32_FIND_DATA fData;/存储文件信息f1=FindFirstFile(e:/teaching/*,55,在程序中得到某个路径下的文件,while(FindNextFile(f1,56,关闭文件查找句炳,HANDLE f1;/句柄WIN32_FIND_DATA fData;/存储文件信息f1=FindFirstFile(e:/teaching/*,57,课堂练习 写成代码,打开图像文件/假设是raw格式的正方形图像 8bit/pixel如果打开失败,处理失败,退出申请动态数组 如果申请失败,关闭图像文件,处理内存申请失败,退出将图像数据读入动态数组 关闭图像文件 处理数组,进行二值化/if pixel 100 pixel=0 else pixel=255创建新文件 如果创建失败,释放内存,处理创建失败,退出将新数组写进新文件释放动态数组关闭新文件程序结束,58,内容提要,输入输出流文件操作作业,59,作业,书上:阅读V2版的11.7(或V5版的15.7)完成练习 V2版的11.12(或V5版的15.12)几何形体练习3以几何形体练习2为基础在基类中加两个虚函数setfromfile(),printtofile()分别用于文件读写,文件统一后缀.geo,在输入文件名时不必输入。向文件输出时注意在每个输出后要输出 或n,否则从文件输入时会出错。从文件输入时,只能屏幕输出,输出结果是按周长大小排序的。而从键盘输入时可以选择是屏幕输出还是文件输出,但都是按面积大小排序的。这点区别请注意。文件压缩,题目描述放在作业网页上。可以迟些(1-2周)交这个作业。,60,强制类型转换运算符,static_cast(a)将地址a转换成类型T,T和a必须是指针、引用、算术类型或枚举类型。表达式static_cast(a),a的值转换为模板中指定的类型T。在运行时转换过程中,不进行类型检查来确保转换的安全性。classB.;classD:publicB.;voidf(B*pb,D*pd)D*pd2=static_cast(pb);/不安全,pb可能只是B的指针 B*pb2=static_cast(pd);/安全的.,61,强制类型转换运算符,dynamic_cast(a)完成类层次结构中的提升。T必须是一个指针、引用或无类型的指针。a必须是决定一个指针或引用的表达式。表达式dynamic_cast(a)将a值转换为类型为T的对象指针。如果类型T不是a的某个基类型,该操作将返回一个空指针。,classA.;classB.;voidf()A*pa=newA;B*pb=newB;void*pv=dynamic_cast(pa);/pv现在指向了一个类型为A的对象.pv=dynamic_cast(pb);/pv现在指向了一个类型为B的对象,62,强制类型转换运算符,const_cast(a)去掉类型中的常量,除了const或不稳定的变址数,T和a必须是相同的类型。表达式const_cast(a)被用于从一个类中去除以下这些属性:const,volatile,和_unaligned。,classA.;voidf()constA*pa=newA;/const对象 A*pb;/非const对象/pb=pa;/这里将出错,不能将const对象指针赋值给非const对象 pb=const_cast(pa);/现在OK了.,63,强制类型转换运算符,reinterpret_cast(a)任何指针都可以转换成其它类型的指针,T必须是一个指针、引用、算术类型、指向函数的指针或指向一个类成员的指针。表达式reinterpret_cast(a)能够用于诸如char*到int*,或者One_class*到Unrelated_class*等类似这样的转换,因此可能是不安全的。,classA.;classB.;voidf()A*pa=newA;void*pv=reinterpret_cast(pa);/pv现在指向了一个类型为B的对象,这可能是不安全的.,64,static_cast和reinterpret_cast区别,假设你想把一个int转换成double,以便让包含int类型变量的表达式产生出浮点数值的结果。如用C风格的类型转换,你能这样写:int firstNumber,secondNumber;double result=(double)firstNumber)/secondNumber;如果用上述新的类型转换方法,你应该这样写:double result=static_cast(firstNumber)/secondNumber;这样的类型转换不论是对人工还是对程序都很容易识别。reinterpret_casts的最普通的用途就是在函数指针类型之间进行转换。其的转换结果几乎都是执行期定义(implementation-defined)。因此,使用reinterpret_casts的代码很难移植。typedef void(*FuncPtr)();FuncPtr funcPtrArray10;funcPtrArray0=,

    注意事项

    本文(程序设计实习第十八讲输入输出流和文件操作.ppt)为本站会员(sccc)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开