已阅读5页,还剩38页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第10章文件读写 教学提示 存储在变量和数组 即内存 中的数据是临时的 这些数据在程序运行结束后会消失 而文件可以用来永久地保存大量的数据 如果有些数据需要反复使用或永久保存 应该考虑使用文件来完成 教学要求 本章要掌握文件在读写之前必须打开 读写结束必须关闭 文件可按只读 只写 读写 追加四种操作方式打开 同时还必须指定文件的类型是二进制文件还是文本文件 文件可按字节 字符串 数据块为单位读写 文件也可按指定的格式进行读写 文件内部的位置指针可指示当前的读写位置 移动该指针可以对文件实现随机读写 10 1文件概述与文件指针 所谓 文件 是指一组相关数据的有序集合 我们在前几章中已多次接触使用过文件 例如源程序文件 目标文件 可执行文件 库文件 头文件 等 10 1 1文件分类 文件通常是驻留在外部介质 如磁盘等 上的 在使用时才调入内存中来 C语言把文件看作是由一个个字符 字节 的数据顺序组成的 它把数据看作是连续的字符 字节 流 这样它对文件的存取实际上是以字符 字节 为单位的 输入输出的数据流的开始和结束只受程序的控制而不受特定符号 比如回车换行符 的控制 也就是说 C语言在输出数据到文件中时 并不会自动增加回车换行符以示结束 在输入时也不会以读入回车换行符作为数据的间隔 10 1 1文件分类 从用户的角度看 文件可分为普通文件和设备文件两种 根据文件的存储形式 可分为ASCII码文件和二进制文件两种 1 ASCII文件也称为文本文件 这种文件在磁盘中存放时每个字符对应一个字节 用于存放对应的ASCII码 例如一个整型数据1234在文本文件中占4个字节 我们用Windows自带的记事本软件打开该类型文件能读懂文件中的内容 2 二进制文件是按二进制的编码方式来存放文件的 例如一个整型数据230在二进制文件中占2个字节 10 1 2文件类型指针 在 语言中要使用文件 必须用一个指针变量指向一个文件 这个指针称为文件指针 通过文件指针就可对它所指的文件进行各种操作 定义文件指针的一般形式为 FILE 指针变量标识符 其中FILE必须为大写 它是在头文件stdio h中定义的一个结构体 该结构体中含有文件名 文件状态和文件当前位置等信息 我们编程时不必关心FILE结构的细节 例如 FILE fp 表示定义了一个名为fp的文件指针 如果变量fp已被正确赋值 则可以根据结构变量fp所提供的信息找到一个文件并实施对该文件的操作 习惯上把fp称为指向一个文件的指针 10 2文件的打开与关闭 使用文件必须遵循 先打开 再对文件进行读写操作 最后关闭文件 的原则 在 语言中 对文件的这些操作都可以由库函数来完成 对用到的库函数的声明包含在文件stdio h中 因此在编程中要操作文件时 要使用头文件包含命令 include stdio h 10 2 1文件的打开 所谓打开文件 实际上是获得文件的各种有关信息 并使文件指针指向该文件 以便进行下一步操作 C语言提供了函数fopen来打开文件 其使用格式为 文件指针名 fopen 文件名 使用文件方式 其中 文件指针名 必须是已被说明为FILE类型的指针变量 文件名 是将被打开的文件的文件名 通常是字符串常量或字符串数组 注意路径的分隔符应使用 使用文件方式 是指文件的类型和操作要求 是一个由一对双引号括起来的字符串 共有12种 具体的符号表示和含义见表10 1 fopen打开文件 例如 FILE fpTa fpTa fopen c cprogram abc rb 反斜线 中的第一个表示转义字符 其意义是打开C驱动器磁盘的cprogram子目录下的文件abc 这是一个二进制文件 只允许按二进制方式进行读操作 又如 FILE fp fp fopen mytest1 txt r 其意义是在当前目录下打开文件mytest1 txt 只允许进行 读 操作 并使fp指向该文件 10 2 2文件关闭函数 在使用完一个文件以后 应该将该文件关闭 以防止它再被调用或丢失数据 关闭 就是使文件指针变量不再指向该文件 也就是文件指针变量与该文件 断开 此后不能通过该指针对原来与其相联系的文件进行读 写操作 除非再次打开该文件 使文件指针变量重新指向该文件 fclose 函数用来关闭一个已经由fopen 函数打开的文件 正常完成关闭文件操作时 fclose函数返回值为0 有错误发生则返回非零值 其调用的一般形式为 fclose 文件指针 例如 fclose fp 10 3文件位置指针的有关函数 在文件内部有一个位置指针 用来指向文件的当前读写字节 在文件打开时 该位置指针总是指向文件的第一个字节 使用下面章节介绍的fgetc等函数对文件进行读写后 该位置指针将自动向后移动 但文件指针和文件内部的位置指针不是一回事 文件指针是指向整个文件的 须在程序中定义说明 只要不重新赋值 文件指针的值是不变的 文件内部的位置指针用以指示文件内部的当前读写位置 每读写一次 该指针均自动向后移动 它不需在程序中定义说明 而是由系统自动设置的 顺序读写和随机读写 文件的读写方式分为顺序读写和随机读写 1 顺序读写即读写文件只能从头开始 顺序读写各个数据 但在实际问题中常要求只读写文件中某一指定的部分 为了解决这个问题可移动文件内部的位置指针到需要读写的位置 再进行读写 这种读写称为随机读写 2 随机读写可以通过利用系统函数去主动移动文件内部的位置指针来实现 这样的函数主要有两个 即rewind函数和fseek函数 实现随机读写的关键是要按要求移动位置指针 这称为文件的定位 在移动位置指针之后 即可用后面介绍的任一种读写函数进行读写 由于一般是读写一个数据据块 因此常用fread和fwrite函数 rewind函数 rewind函数的功能是把文件内部的位置指针移到文件首 其调用形式为 rewind 文件指针 文件指针 指向被移动的文件 fseek函数 fseek函数用来移动文件内部位置指针 其调用形式为 fseek 文件指针 位移量 起始点 其中 文件指针 指向被移动的文件 位移量 表示移动的字节数 要求位移量是long型数据 以便在文件长度大于64KB时不会出错 当用常量表示位移量时 要求加后缀 L 起始点 表示从何处开始计算位移量 规定的起始点有三种 文件首 当前位置和文件尾 例如 fseek fp 100L 0 将文件位置指针移到离文件头100个字节处 fseek fp 20L 1 将文件位置指针从当前位置后移20个字节的位置 fseek fp 10L SEEK END 将文件位置指针从文件末尾前移10个字节的位置 注意 fseek函数一般用于二进制文件 在文本文件中由于要进行转换 往往计算的位置会出现错误 ftell函数 用来得到流式文件中的当前位置 用相对于文件开头的位移量来表示 如返回 1L则表示出错 例如 longa a ftell fp 文件结束检测函数feof函数feof 判断文件是否处于文件结束位置 如文件结束 则返回值为1 否则为0 其调用格式为 feof 文件指针 说明 文件结束标志EOF 每个文件末有一结束标志EOF 值为 1 只适用于判断文本文件是否结束 而函数feof 则对文本文件和二进制文件都适用 10 4读写文件 10 4 1字符读写函数fgetc和fputc是以字符 字节 为单位的读写函数 每次可从文件读出或向文件写入一个字符 字符输入 出函数所处理的文件可以是文本文件 也可以是二进制文件 10 4 2字符串读写函数fgets和fputs处理的文件一般是文本文件 读写的数据以字符串为单位 10 4 3数据块读写函数fread和fwtrite用于整块数据的读写函数 可用来读写一组数据 如一个数组 一个结构变量的值等 10 4 4格式化读写函数fscanf和fprintf与前面使用的scanf和printf函数的功能相似 都是格式化读写函数 两者的区别在于fscanf函数和fprintf函数的读写对象不是键盘和显示器 而是磁盘文件 读字符函数fgetc fgetc函数的功能是从指定的文件中读取一个字符 函数调用的一般形式为 字符变量 fgetc 文件指针 例如 ch fgetc fp 其意义是从打开的文件fp中读取一个字符并送入字符变量ch中 对于fgetc函数的使用有以下几点说明 1 在fgetc函数调用中 读取的文件必须是以读或读写方式打开的 2 读取字符的结果也可以不向字符变量赋值 例如fgetc fp 但是读出的字符不能保存 3 文件内部的位置指针在文件打开时总是指向文件的第一个字节 使用fgetc函数后 该位置指针将向后移动一个字节 因此可连续多次使用fgetc函数来读取多个字符 例10 1 将C盘根目录下的文本文件test1 txt的内容在屏幕上输出 includemain FILE fp 定义了文件指针fp charch if fp fopen c test1 txt r NULL 以读文本文件方式打开并使fp指向该文件 printf nCannotopenfile strikeanykeytoexit getchar exit 1 ch fgetc fp 先读出一个字符 然后进入循环 while ch EOF 判断文件是否结束 putchar ch 把该字符显示在屏幕上 ch fgetc fp 再读入下一字符 fclose fp printf n 本例程序的功能是从文件中逐个读取字符 并在屏幕上显示 如打开文件出错 给出提示并退出程序 只要读出的字符不是文件结束标志EOF 就把该字符显示在屏幕上 再读入下一字符 每读一次 文件内部的位置指针向后移动一个字符 文件结束时 该指针指向EOF 执行本程序将显示文件c test1 txt的所有内容 写字符函数fputc fputc函数的功能是把一个字符写入指定的文件中 如写入成功则返回写入的字符 否则返回一个EOF 可用此来判断写入是否成功 函数调用形式为 fputc 字符量 文件指针 字符量是待写入的字符常量或变量 例如 fputc x fp 其意义是把字符 x 写入fp所指向的文件的位置指针的当前位置中 每写入一个字符 文件内部位置指针向后移动一个字节 被写入的文件可以用写 读写 追加方式打开 例10 2 将从键盘上输入的一些字符 以 作为结束 写入c盘根目录下名为test2 txt的文本文件中 include stdio h main FILE p charch if p fopen c test2 txt w NULL printf Filecannotopen n exit 0 printf Pleaseinput endinputwith character while ch getchar fputc ch p fclose p printf Writeover n 程序运行结束后 可以在c盘根目录下打开test2 txt查看其内容 思考一下 如果在写入完毕后想马上把刚才输入的内容打印在屏幕上该如何实现 字符串输入 出函数 字符串输入 出函数所处理的文件一般是文本文件 读写的数据以字符串为单位 1 读字符串函数fgets功能是从指定的文件中读一个字符串到字符数组中 函数调用的形式为 fgets 字符数组名 n 文件指针 其中n是一个正整数 该函数表示从文件中读出n 1个字符 如在读满n 1个字符之前就遇到了换行符或EOF 则读出提前结束 并在读取的最后一个字符后加上串结束标志 0 fgets函数的返回值是字符数组的首地址 读取字符串后文件位置指针也自动后移若干个位置 例如 fgets str n fp 意义是从fp所指的文件中读出n 1个字符送入字符数组str中 例10 3 从test2 txt文件中读入8个字符组成一个字符串 includemain FILE fp chararr 20 if fp fopen c test2 txt r NULL printf nCannotopenfile strikeanykeyexit getchar exit 1 fgets arr 9 fp printf n s n arr fclose fp 本例定义了一个字符数组str共20个字节 在以读文本文件方式打开文件string后 从中读出8个字符送入str数组 在第9个数组元素str 8 内加上 0 然后在屏幕上显示输出str数组存放的字符串 输出的八个字符正是例10 2的前八个字符 2 写字符串函数fputsfputs函数的功能是向指定的文件写入一个字符串 不写入字符串结束标记 0 当成功写入一个字符串后 文件的位置指针会自动后移 函数返回值为0 否则 返回EOF 符号常量 其值为 1 其调用形式为 fputs 字符串 文件指针 其中字符串可以是字符串常量 也可以是字符数组名或指针变量 例如 fputs a1b2 fp 是把字符串 a1b2 写入fp所指的文件之中 例10 4 在文件test2 txt中追加一个不超过20个字符的字符串 includemain FILE fp charch st 21 intcount if fp fopen c test2 txt a NULL printf Cannotopenfilestrikeanykeyexit getchar exit 1 printf inputastring n gets st 输入不超过20个字符的字符串暂放入数组st中 fputs st fp rewind fp 文件内部位置指针移到文件的开始位置 printf nAllofthisfileis n ch fgetc fp while ch EOF putchar ch ch fgetc fp printf n fclose fp 本例要求在test2 txt文件末添加一个字符串 因此 在程序第7行以追加读写文本文件的方式打开文件test2 txt 然后输入字符串暂放入数组st中 并用fputs函数把该串写入文件test2 txt 后在程序中用rewind函数把文件内部位置指针移到文件首 再进入循环逐个显示当前文件中的全部内容 要注意用scanf s st 和gets st 输入字符串时的不同 思考 如果不用EOF 而是用feof 来判断文件结束 上述阴影部分程序该如何改写 数据块读写函数fread和fwtrite 语言还提供了用于整块数据的读写函数 可用来读写一组数据 如一个数组 一个结构变量的值等 读数据块函数调用的一般形式为 fread buffer size count fp 写数据块函数调用的一般形式为 fwrite buffer size count fp 其中 size表示每个数据块的字节数 count表示要读写的数据块块数 fp表示文件指针 buffer是一个指针 fread buffer size count fp 的功能是从fp所指向文件的位置指针的当前位置读取count块数据 每个数据所占的字节数为size 共组成count块长度为size的数据存入butter所指定的内存空间中 当正确的读取了count块数据后 文件内部指针会自动后移count size个字节的位置 若数据存入正确 则返回count值 否则返回NULL 符号常量 其值为0 例如 fread fa 4 5 fp 其意义是从fp所指的文件中 每次读4个字节 一个实数 送入实型数组fa中 连续读5次 即读5个实数到fa中 fwrite buffer size count fp 表示将从buffer起始地址的count块数据 每块数据的字节数为size 写入到fp所指向的文件中 当正确的写入count块数据后 文件位置指针会自动后移count size个字节的位置 若数据写入正确 则返回count值 否则返回NULL 符号常量 其值为0 例10 5 从键盘上输入10个整数 并把这些整数写入c 盘根目录下名为test3 dat的二进制文件中 include stdio h main FILE fp intdata 10 i if fp fopen c test3 dat wb NULL printf Filecannotopen n exit 0 printf Inputtenintegers for i 0 i 10 i scanf d 例10 6 从c 盘根目录下名为test3 dat的二进制文件中读取10个整数 要求先读取第6 10个整数 再读取第1 5个整数 并把它们输出到屏幕上显示 include stdio h main FILE fp intdata 10 i if fp fopen c test3 dat rb NULL printf Filecannotopen n exit 0 fseek fp 5L sizeof int 0 先把文件位置指针后移 fread data sizeof int 5 fp 先读取第6 10个整数放入data 0 data 4 rewind fp 把文件位置指针移到文件开始 fread data 5 sizeof int 5 fp 再读取第1 5个整数放入data 5 data 9 fclose fp for i 0 i 10 i printf 5d data i 例10 7 从键盘输入三个学生数据 写入一个文件中 再读出这两个学生的数据显示在屏幕上 includestructstu charname 20 intnum intage charaddr 30 boya 3 boyb 3 pp qq main FILE fp inti pp boya qq boyb if fp fopen c studata wb NULL printf Cannotopenfilestrikeanykeyexit getchar exit 1 for i 0 iname 本例程序定义了一个结构stu 说明了两个结构数组boya和boyb以及两个结构指针变量pp和qq pp指向boya qq指向boyb 程序首先以读写方式打开二进制文件 studata 输入三个学生数据之后 写入该文件中 然后把文件内部位置指针移到文件首 读出三块学生数据后 在屏幕上显示 格式化读写函数fscanf和fprintf fscanf函数 fprintf函数与前面使用的scanf和printf函数的功能相似 都是格式化读写函数 两者的区别在于fscanf函数和fprintf函数的读写对象不是键盘和显示器 而是磁盘文件 这两个函数的调用格式为 fscanf 文件指针 格式字符串 输入表列 fprintf 文件指针 格式字符串 输出表列 例如 fscanf fp d s 用fscanf和fprintf函数也可以完成例10 7的问题 修改后的程序如例10 8所示 例10 8 用fscanf和fprintf函数解决例10 7的问题 includestructstu charname 20 intnum intage charaddr 30 boya 3 boyb 3 pp qq main FILE fp inti pp boya qq boyb if fp fopen c studata wb NULL printf Can topenfilestrikeanykeyexit getch exit 1 printf ninputdata n for i 0 iname 本程序中fscanf和fprintf函数每次只能读写一个结构体数组元素 因此采用了循环语句来读写全部数组元素 还要注意指针变量pp qq 由于循环改变了它们的值 因此在程序中分别对它们重新赋予了数组的首地址 例10 9 把命令行参数中的前一个文件名标识的文件 复制到后一个文件名标识的文件中 如命令行中只有一个文件名则把该文件写到标准输出文件 显示器 中 includemain intargc char argv FILE fp1 fp2 charch if argc 1 如命令行参数中没有给出文件名 则给出提示信息 printf Havenotenterfilename strikeanykeyexit getchar exit 0 if fp1 fopen argv 1 rt NULL printf Cannotopen s n argv 1 getchar exit 1 if argc 2 如果只给出一个文件名 则使fp2指向标准输出文件 即显示器 fp2 stdout elseif fp2 fopen argv 2 wt NULL printf Cannotopen s n argv 1 getchar exit 1 while ch fgetc fp1 EOF 用循环语句逐个读出文件1中的字符再送到文件2中 fputc ch fp2 fclose fp1 fclose fp2 本程序为带参数的main函数 程序中定义了两个文件指针fp1和fp2 分别指向命令行参数中给出的文件 如命令行参数中没有给出文件名 则给出提示信息 如果只给出一个文件名 则使fp2指向标准输出文件 即显示器 然后用循环语句逐个读出文件1中的字符再送到文件2中 假设项目名称为cexam1 1 则生成一个可执行文件cexam1 1 exe 在DOS下运行结果如图所示 第一次运行 不指定文件名 系统提示 havenotenterfilename strikeanykeyexit 再次运行时 给出了一个文件名test1 txt 故输出给标准输出文件stdout 即在显示器上显示文件test1 txt的内容 1234 第三次运
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论