C_C++程序设计教程课件文件_第1页
C_C++程序设计教程课件文件_第2页
C_C++程序设计教程课件文件_第3页
C_C++程序设计教程课件文件_第4页
C_C++程序设计教程课件文件_第5页
已阅读5页,还剩40页未读 继续免费阅读

下载本文档

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

文档简介

1、一、文本流和二进制流二、流文件三、文件的翻开函数fopen和关闭函数fclose四、格式读写fprintf和fscanf函数五、出错测试或去除函(feof,ferror,clearerr)第13章 文 件 1一、文本流和二进制流 内存中的信息会由于程序运行的结束而消失。程序运行的结果需要另外稳定的介质加以永久保存,这种可以长期保留数据的存储设备称为磁盘文件。下面几种是有影响的存储方式: 1. ANSI C 运行库缓冲流的输出输出操作 2. C 运行库低级输出输出操作 3. iotream类提供的I/O操作 4. DOS 或WINDOWS API 端口操作 5. Microsoft Founda

2、tion 类库的文件操作 2在C/C+中流可分为两类: 1) 文本流(text stream); 1) 二进制流(binary stream) 文本流中的数据以字符形式出现,文本以行作为结束。 图 数据的流入流出是一个相对概念 流 入 couta 流 入 磁盘 内存 缓冲区 内存 数据区 键盘 stdin stdout显示器 stderr 打印机 stdprn3二、流文件 流文件是C运行库函数中由FILE结构有效处理的硬件设备的逻辑描述。在这个称为标准文件I/O系统中, 定义了三个文本流: stdin,stdout和stderr。一般对如下前3个标准设备,系统构筑了流文件的索引方式,其相应的非

3、缓冲区的文件代号一并罗列如下: 硬件设备 预定义的流文件或流对象 设备代号或句柄键 盘标准输入 stdin cin 0 显示器标准输出 stdout cout 1显示器标准错误 stderr cerr 2串行口标准辅助 stdaux 3打印机标准打印 stdprn clog 4 4 描述流文件的FILE数据结构随编译器版本的不同而相异,下面的描述摘自微软VC 6.0 头文件stdio.h,该结构的具体声明如下: struct _iobuf char *_ptr; /1索引数据流内容的位置指针 int _cnt; /2当前的定位标志数 char *_base; /3缓冲区基准位置 int _fl

4、ag; /4文件操作模式标记 int _file; /5文件的代号 int _charbuf; /6字符缓冲信息 int _bufsiz; /7缓冲区大小 char *_tmpfname; /8临时文件名;typedef struct _iobuf FILE;5 对于该结构软件供给商并未逐一指明其中每一数据成员的详细含义,标准输入输出函数的用户不要冒然直接去操作其中的成员,而通过相应的函数间接进行。 三个预定义的流文件在vc 6.0的stdio.h中通过通过外部说明语句和宏: extern FILE _iob ;#define stdin (&_iob0)#define stdout (&_i

5、ob1)#define stderr (&_iob2) 就已经在内存中构建, 因此不对这三个标准的I/O设备进行建立和去除工作。但其它的流文件需要程序员调用相关的函数,进行规那么的内存分配和释放工作。6三、文件的翻开函数fopen和关闭函数fclose1. 文件的翻开函数fopen 文件的翻开函数fopen是为要操作的磁盘文件对应的数据结构分配内存的函数,这是一个构建FILE的数据结构变量的初始化函数,系统通过调用类似malloc的堆内存分配函数完成了FILE型结构变量的内存分配。下面是fopen函数一个简约的函数原型: FILE * fopen (const char *filename,

6、const char *mode); 函数返回一个指向堆空间的FILE *型的流文件指针。不如确切地说该函数在堆空间诞生了一个FILE型结构变量。7 两个const char *型的入口参数对上面的结构成员执行了局部初始化赋值。第一个参数filename是定位磁盘文件路径的文件名,该文件名通常是双引号括起来的只读字符串。 在使用含路径的文件名时,注意“的使用,对于硬盘中的文件d:mydocu_1ex.cpp 应写成 “d:mydocu_1ex1.cpp 或进行如下的初始赋值:const char *filename=d:mydocu_1ex1.cpp; 第二个以只读字符串的形式出现的参数mod

7、e,界定文件访问操作的模式。其有效的取值组合和含义见下一页 8mode 含义 r 以read only 方式翻开一个文本文件,如果 输入文件不存在或未找到fopen失败 w 以write only方式翻开一个文本文件,如果 输出文件已存在,内容将全覆盖 a 以写和append方式在文本文件末尾追加,如 果它不存在那么先建立该文件 r+ 以读或写的方式翻开一个必须已经存在的文 本文件 w+ 以读或写的方式翻开一个空文件,如果给定的 文件名存在原来的内容将被冲洗 a+ 以读/写和追加方式翻开文件,如果该文件不存 在那么先建立它9 rb 以只读方式翻开一个binary输入文件,如果文件 不存在或未找

8、到fopen失败 wb 以只写方式翻开一个二进制输出文件,如果文件 已存在,内容将全覆盖 ab 以append方式在binary文件末尾追加,如果它 不存在那么先建立该文件 rb+ 以读或写的方式翻开一个必须已经存在的二进制 文件 wb+ 以读或写的方式翻开一个空binary文件,如果文 件名存在原来的内容将被销毁 ab+ 以读和追加方式翻开二进制文件,如果该文件不 存在那么先建立它10 指定文件的缺省操作类型取决于一个全局变量 _fmode,vc6.0 里在头文件stdlib.h中声明为extern int _fmode;,系统设置的默认值是文本方式即: _fmode=O_TEXT=0 x4

9、000 如果从文本方式切换为二进制模式,可以在程序中令: _fmode= O_BINARY; 如果在翻开文件发生错误,那么fopen都返回NULL即0,其潜在的原因有: a. 以读模式翻开一个并不存在的文件 b. 翻开一个无权操作的文件如该文件已标明只读或隐藏属性试图写追加翻开 c. 以追加方式对文件操作但磁盘空间缺乏112.文件的关闭函数fclose 函数fclose专用于释放由函数fopen申请的堆空间,及时完成缓冲区数据的到位。fclose的函数原型为: int fclose (FILE * fp);fclose的函数原型为:int fclose (FILE * fp); 其中入口形参匹

10、配函数fopen返回的指针值,函数fclose调用成功返回数值0,否那么返回EOF即-1。 该函数不操作预定义的流文件stdin,stdout和stderr,它们是指向全局结构变量的指针。这样函数调用: fclose (fp); 就关闭了先前由fopen函数翻开的文件指针所对应的堆空间。12四、格式读写fprintf和fscanf函数 1. fprintf输出函数 fprintf输出函数的一般形式为: int fprintf (FILE* pTarget, const char* format, argument_list); int fprintf (流文件的目的地,格式控制串,参量列表);

11、 fprintf函数格式控制串与printf中的相同。将fprintf 的第一个形参pTarget取为实参stdout,其调用格式相当于printf函数。即 fprintf (stdout,格式控制串,参量列表); 相当于: printf (格式控制串,参量列表); 13 在使用fprintf将内存数据写到磁盘文件之前,先要指明磁盘文件的目的所在,因此通过fopen函数的写模式获得目标地址。如: FILE *fpWrite= fopen (writeFile , w);如此之后就可以调用的 fprintf 函数.如: fprintf (fpWrite, format, v_list); fpr

12、intf (流文件目的地, 格式控制串, 变量列表);142. fscanf输入函数 fscanf函数的一般形式为: int fscanf (FILE* pSource, const char* format, address_list); int fscanf (流文件的来源处, 格式控制串, 变量的地址列表; 将fscanf的第一个形参pSource实参化为stdin,其调用格式相当于scanf函数。即: fscanf ( stdin, 格式控制串, 变量地址1, 变量地址2 . 变量地址n);相当于: scanf (格式控制串, 变量地址1, 变量地址2 . 变量地址n); 15 在调用

13、fscanf函数将磁盘源文件中的数据送到变量所占住的内存之前,先应指明待读的磁盘文件,因此借助fopen函数的读模式得到数据源流的地址如: FILE *fpRead= fopen (readFile, r);如此之后就可以调用输入函数fscanf。格式为: fscanf (fpRead, format, address_list);16 例 格式转换处理一个结构变量.#include typedef struct SData int nLineset; float fAdjust; int nPoint; float fXa; float fYa; float fZa; CData; void

14、 OutputData (const char *filename, const CData &d ) FILE *fp= fopen(filename, w); fprintf (fp,%d,%f,%dn,d.nLineset,d.fAdjust,d.nPoint);/1 fprintf (fp,%f,%f,%fn, d.fXa,d.fYa,d.fZa);/2 fclose (fp); 17void InputData (const char *filename, CData &d ) FILE *fp = fopen (filename, r); fscanf (fp, %d, %f, %

15、d, &d.nLineset, &d. fAdjust, &d.nPoint); fscanf (fp,%f,%f,%f, &d.fXa, &d.fYa, &d.fZa); /2 fclose (fp); 18void main (void) CData s= 1,2,3,4,5,6; OutputData (c:sdata.out, s); CData d; InputData (c:sdata.out, d); OutputData (c:cdata.out, d); 在文件c:cdata.out中输出结果为: 1,2.000000,3 4.000000,5.000000,6.000000

16、在文件c:sdata.out中输出结果为: 1,2.000000,3 4.000000,5.000000,6.00000019五、出错测试或去除函(feof,ferror,clearerr)1. feof函数测试文件结束标志 feof函数的原型为: int feof (FILE *stream);该函数的调用格式常为: while (!feof (stream) 读写循环体;2. ferror函数测试流中的错误 ferror函数的原型为: int ferror (FILE *stream);3. clearerr函数去除错误标志为0 clearerr函数原型为: void clearerr (

17、FILE *stream);20六、字符和字符串读写函数七、无格式转换的读写函数fread和fwrite八、文件的定位九、一个简单的读写存盘程序步骤第13章 文 件 21六、字符和字符串读写函数 1. 读取单个字符的fgetc函数 fgetc函数的原型为: int fgetc (FILE * pSrcFile); FILE*型的入口形参指明读取操作的来源, 实参匹配 fopen翻开的磁盘文件或stdin。 该函数从磁盘文件的当前位置读取一个字符, 定位源磁盘文件的位置指针向后移动一个字节。如果该指针到达文件末尾,fgetc函数返回EOF。 注意例程getc与函数fgetc作用相同但可以作为函数

18、和宏出现。getchar()例程与getc(stdin)一致,亦可以作为函数和宏出现。 22例fgetc.cpp# include void main(void) FILE* fpGet =fopen (fgetc.cpp,r); if (fpGet=NULL) printf (fopen failedn); return; int i=0; char buffer512; while (feof (fpGet)=0 & i512) buffer i+= fgetc (fpGet); bufferi=0; printf (%sn,buffer); /fclose (fpGet); /程序运行的

19、结果显示fgetc.cpp在屏幕上 232. 存写单个字符的fputc函数 fputc函数的原型为:int fputc (int ch, FILE * pDstFile); fputc函数的第一个形参ch正是要存写到第二个形参pDstFile关联的磁盘文件中去的字符,该函数返回第一个入口形参的实参值。 pDstFile匹配一个fopen返回的流文件指针或stdout,调用失败返回EOF。 24例 fputc.cpp # include void main (void) FILE* fpGet = fopen (fputc.cpp, r); if ( fpGet = NULL) printf (

20、fopen failedn); return; FILE* fpPut = fopen (fputc.xpp,w); if ( fpPut = NULL) printf (fopen failedn); return; while (!feof ( fpGet ) /while (feof (fpGet)=0) fputc (fgetc (fpGet), fpPut); fclose ( fpGet ); fclose ( fpPut ); 25 程序运行之后即将上面的fputc.cpp源程序转存到fputc.xpp中。 上面单个输入输出函数其返回类型是int型的数值,虽然处理的是仅一个字节长

21、的字符。 因此接受这些函数的结果的变量最好定义成int型变量即: int ch1= fgetc ( pSrcFile ); 函数一般地会自动进行截断整型高位数的处理而只存写低位。 而能不失包容性地应付占两个字节的重要结尾信息EOF(-1)。263. 按行读文本串fgets函数函数fgets的原型为:char * fgets(char *pDstBuffer, int num, FILE * pSrcFile); FILE *型的入口形参pSrcFile定位数据的来源,匹配实参stdin或fopen函数读模式返回的流文件的指针,从中读取num-1个字符到char*的入口形参pDstBuffer标

22、明的字符缓冲区,pDstBuffer也就是该函数的返回地址。 如果在读取num-1个字符之前遇到换行符n那么读入结束;然后添补一个0字符,以表示字符串的规那么结束。 暗地里定位源磁盘文件的位置指针向后移动字符缓冲区实际拥有的字节数.pDstBuffer 匹配一个足够大的字符数组.27例 fgets.cpp # include void main (void) FILE* fp=fopen ( fgets.cpp,r ); if ( fp=NULL ) printf (fopen failedn); return; char sBuffer128; for ( int k=0;k9;k+ ) i

23、f ( fgets ( sBuffer,128,fp )! = NULL) printf ( %s, sBuffer ); fclose ( fp ); /程序运行的结果显示 fgets.cpp在屏幕上。284. 按行写文本串fputs函数 函数fputs的原型为: int fputs (const char *pSrcBuffer, FILE * pDstFile); 文本文件的操作一般按行进行,一行一行地读一行一行地写,fgets函数执行按行读的操作,函数fputs那么按行写。 fputs函数将第一个形参定位的只读字符串送到送到第二个形参指明的目的文件中的当前位置。 如果调用成功函数返回正

24、数,在出现错误时返回EOF。29例 fputs.cpp # include void main(void) FILE* fpRead = fopen (fputs.cpp,r); if ( fpRead = NULL ) printf ( fopen r failedn ); return; FILE* fpWrite = fopen ( fputsw.cpp, w) ; if ( fpWrite = NULL ) printf ( fopen w failedn ); return; 30 char s 81; while ( !feof ( fpRead ) /while ( feof (

25、 fpRead ) = =0) if ( fgets ( s, 81, fpRead )! = NULL ) fputs (s, fpWrite ); printf ( %s, s ); fclose ( fpWrite ); /程序运行显示fputs.cpp在屏幕上同时拷贝了一个备份在磁盘文件fputsw.cpp中31七、无格式转换的读写函数fread和fwrite 函数直接读写磁盘文件的二进制数据,读写过程数据的信息未发生转换。因而空间效率和时间效率都比较高。 1. 函数fread的原型为: size_t fread (void * pDst, size_t size, size_t it

26、ems , FILE * pSrc); 第一个参数pDst定位读取数据的存放位置,匹配任意集合类型的起始地址。 第二个参数size指出数据的类型大小; size = sizeof ( type )。 32 第三个参数items指出数据的最大项数,常对应数组的维数,单一变量或对象常取1。 第四个参数是FILE * 型的入口形参pSrc,指明读入数据的来源。 fread返回实际读取的项数,函数从输入文件中最多读取items项数,每一项含有size字节,并将它们放入pDst起始的内存中。 如果错误发生那么所读的结果是游移的。 与pSrc关联的位置指针向后移动实际读取的字节数。332. fwrite存

27、写函数函数fwrite的原型为: size_t fwrite(const void * pSrc, size_t size, size_t items, FILE * pDst ); 一般地fread总是读取原先由frwite存写的二进制数据; 第一个参数入口形参pSrc定位所写数据的源位置,匹配任意集合类型的起始地址。 第四个参数入口形参 pDst指向待存写的目的地即与pDst相关联的磁盘文件。 其余两个参数同fread函数。 34 函数fwrite 返回实际所存写的数据项的个数,如出现错误返回值可少于items。 fwrite函数从pSrc定位地址起尽量转送items个数据项到输出流文件中

28、,位置指针递增实际所写的字节数。 上面两个函数都存在void*的指针用于宽泛地定位内存的地址,但由于其模糊性必伴随具有size_t 类型的具体参数严格划定数据的边界,这是void*型形参函数的共性。 一般地fread总是读取原先由frwite 存写的二进制数据。35例直接随机方式处理结构变量和数组 #include typedef struct SData int nLineset; float fAdjust; int nPoint; float fXa; float fYa; float fZa; CData; void WriteData ( CData pSrc , int n, FI

29、LE *fpDst ) switch (n) case 1: fwrite ( pSrc, sizeof (CData), 1 ,fpDst); break; default: fwrite ( pSrc, sizeof (CData), n, fpDst ); inline void ReadData (CData* pDst, int n, FILE *fpSrc ) fread ( pDst, sizeof ( CData ),n,fpSrc ); 36void PrintData ( const CData &d ) printf (“%4d,%4.1f,%4d,%4.1f,%4.1f

30、,%4.1fn, d.nLineset, d.fAdjust, d.nPoint, d.fXa, d.fYa, d.fZa); void main (void) CData s = 0,1,2,3,4,5; CData d = 1,2,3,4,5,6, 2,3,4,5,6,7, 3,4,5,6,7,8; FILE* fpWrite = fopen ( c:cdata.dat, w); if ( fpWrite = NULL) printf ( fopen w failedn ); return; WriteData ( &s, 1, fpWrite ); WriteData ( d, 3, f

31、pWrite ); fclose ( fpWrite ); FILE* fpRead = fopen ( c:cdata.dat, r ); 37 if ( fpRead = = NULL ) printf ( fopen r failedn ); return; CData b 4; ReadData ( b, 3, fpRead ); ReadData ( b+3, 1, fpRead ); for ( int k=0; k4; k+ ) PrintData ( bk ); c:cdata.dat文件的长度为4*6*4=96个字节,屏幕显示结果为: 0, 1.0, 2, 3.0, 4.0,

32、 5.0 1, 2.0, 3, 4.0, 5.0, 6.0 2, 3.0, 4, 5.0, 6.0, 7.0 3, 4.0, 5, 6.0, 7.0, 8.038 fread和fwrite函数因其void*入口参数而可以匹配任意类型的变量地址,而称为随机读写函数。 但实际上数据的类型属性转移到size_t参数上去了,这个size_t参数n=sizeof (type)协同函数在定位好的内存空间中读写数据。 因此数据类型属性的匹配依然是环环相扣不可轻易错位的。即此类型的函数操作此类型的数据。随机读写应根据数据类型的匹配关系为: void WriteData ( CData*pSrc , int n

33、, FILE * fpDst) fwrite (pSrc,sizeof (CData), n, fpDst); void ReadData (CData* pDst ,int n,FILE * fpSrc) fread (pDst,sizeof(CData), n, fpSrc);39八、文件的定位1. ftell函数告知当前位置 FILE结构的声明中有一个char *型指针成员 _ptr即索引数据流内容的位置指针,该指针潜在地指向当前文件的位置。 当用户首次翻开流文件进行读写操作时,操作系统把该位置指针设置在文件的开头。 但特别地以追加方式a翻开文件时,位置指针定位于文件的结尾处。每次读写一个字符时,位置指针向前移动一个字符。 如果从文件中读写一行文本,位置指针一般移到该行末尾或下一行开始处。40 ftell函数告知当前位置函数ftell的原型为: long ftell (FILE * stream); 函数返回的lo

温馨提示

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

评论

0/150

提交评论