版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
本章目录10.1文件概述10.2文件的打开与关闭10.3文件的读写10.4文件的定位10.5错误处理10.1文件概述为了方便大量数据的输入输出和长期存储,有必要在C语言的程序设计中引入文件的知识。“文件”是指记录在外部介质上的数据的集合,是计算机中数据在存储介质上的存在形式。文件通常分为两大类:程序文件和数据文件。程序文件就是通常所说的可执行文件,是计算机指令和少量数据的集合。数据文件只包含待程序文件处理的数据,通常用来存储大量数据,例如:VCD文件、MP3文件、数据库文件。C语言中的程序通过对文件的读、写等操作来实现对外部存储介质(例如磁盘)上数据的物理操作。通过C语言提供的文件操作函数,可以简单、高效、安全地访问外部数据。1.文件类型 文件按其存储数据的格式分为两大类型:文本文件和二进制文件。两种文件格式主要有如下几点区别:1)文本文件由可显示字符组成,如字母、数字、符号;而二进制文件只是若干长度的0、1序列。2)文本文件以字符(8位)为单位写入和读取;二进制文件则以数据块为单位进行读写。3)文本文件用于存储文字信息,说明文件、C语言源程序文件都是文本文件;二进制文件用于存储非文本数据,如二进制执行代码、图像、声音等。10.1文件概述4)文本文件可以直接在屏幕上显示文件内容;二进制文件虽然可以显示,但显示的内容无意义2.文件类型指针 在C语言中引入了文件指针的概念,所有对文件的操作都通过文件指针完成。文件指针类似于C语言中的普通指针,但文件指针不是指向一段内存空间,而是指向一个文件信息结构体,该结构体描述一个文件的相关信息,其定义在stdio.h头文件中。用户无需了解有关此结构体的细节,只需要知道如何使用文件指针即可。声明一个文件指针使用以下语句:FILE*文件指针名1)要使用文件指针进行文件相关操作必须在程序中包含stdio.h头文件。2)“FILE”全是大写字符,若改成小写字母是错误的。3)声明一个文件指针后,就可以使用各种函数打开、关闭文件以及进行读写操作。C语言中,对文件的基本操作可以说就是文件的打开和关闭、文件的读写等操作。10.2文件的打开与关闭在实际应用当中,经常要对文件进行处理,C程序对文件的处理过程一般如下:文件的打开。建立一个新的文件或为存取某一个文件的数据而打开文件对文件进行读、写或其他操作关闭文件。文件使用完后,要关闭文件,保存文件的改写。1.文件的打开(fopen函数)在C语言中文件的打开库函数来实现,其格式如下:FILE*fp;/*声明一个文件指针*/fp=fopen(文件名,打开方式);文件名:是要求打开文件的文件名(包括扩展名),是一个字符串,以双引号括起。如果省略文件路径,则在当前目录下打开文件。打开放式:有只读、只写、追加、读写几种,使用不同的标识符区分。标识符见表9.110.2文件的打开与关闭打开方式标识符含义“r”以只读方式打开一个文本文件。“w”以只写方式打开一个文本文件。“a”以追加方式打开一个文本文件。“r+”以读写方式打开一个文本文件。“w+”以读写方式建立一个新的文本文件。“a+”以读写方式建立一个文本文件。“rb”以只读方式打开一个二进制文件。“wb”以只写方式打开一个二进制文件。“ab”以追加方式打开一个二进制文件。“rb+”以读写方式打开一个二进制文件。“wb+”以读写方式建立一个新的二进制文件。“ab+”以读写方式打开一个二进制文件。表9.110.2文件的打开与关闭例如:
fp=fopen(“abc.txt”,”r”)/*以只读方式打开abc.txt文件*/ fp=fopen(“abc.c”,”r+”)/*以读写方式打开abc.c文件*/fopen()函数的返回值是一个文件信息结构体的地址,该文件信息结构体是描述目标文件的相关信息。调用fopen()函数前必须声明一个文件指针,并使用文件指针接受fopen()函数的返回值。文件指针被赋值后,程序中就通过这个文件指针对目标文件进行操作。若不使用文件指针接受fopen()函数的返回值,则无法对已打开的文件进行访问,调用fopen()函数也是无意义的。如果不能实现“打开”的任务,fopen函数将会带回一个出错信息。出错的原因可能是用“r”方式打开一个并不存在的文件;磁盘出故障;磁盘已满无法建立新文件等。此时fopen函数将带回一个空指针值NULL(NULL在stdio.h文件中已被定义为0)。常用下面的方法打开一个文件:if((fp=fopen(“file”,”r”))==NULL){printf(“cannotopenthisfile\n”);exit(0);}10.2文件的打开与关闭即先检查打开的操作有否出错,如果有错就在终端上输出“cannotopenthisfile”。Exit函数的作用是关闭所有文件,终止正在调用的过程。待用户检查出错,修改后在运行。2.文件的关闭(fclose函数)使用完一个文件之后应该尽快关闭,以免数据丢失。关闭一个文件使用fclose()函数实现,其格式如下:Fclose(文件指针)文件指针:指明要关闭哪个文件,作为参数的文件指针必须是由打开文件函数fopen()得到的。例如:#include<stdio.h>main(){FILE*fp;…if(fp=fopen(“abc.txt,”“r”))==0)/*尝试打开文件*/10.2文件的打开与关闭{文件打开错误处理else{/*打开文件成功*/…
读写文件操作
…fclose(fp);}…}以上程序由打开文件函数fopen()和关闭文件函数fclose()共同构成了包含文件操作的C语言程序框架。abc.txt是文件名。应该养成在程序终止之前关闭所有文件的习惯,如果不关闭文件将会丢失数据,因为,在向文件写数据时,是先将数据输到缓冲区,待缓冲区充满后才正式输出给文件。如果当数据未充满缓冲区而程序结束运行,就会将缓冲区中的数据丢失。用fclose函数关闭文件,可以避免这个问题,它先把缓冲区中的数据输出到磁盘文件,然后才在释放文件指针变量。10.3文件的读写对文件来说,读写操作是非常重要的,常用的读写函数如下:10.3.1fgetc()函数和fputc()函数对文件的操作时一次读写一个字符。1.fgetc()函数从指定的文件读取一个字符,该文件必须是以读或读写方式打开的。其格式如下:charc;c=fgetc(文件指针)文件指针:指向一个已打开的文件,ch为字符变量。fgetc函数的返回值是一个字符,赋给ch。如果在执行fgetc函数读字符时遇到文件结束符,函数返回一个文件结束标志EOF(-1)。如果想从一个磁盘文件顺序读入字符并在屏幕上显示出来,可以如下操作:ch=fgetc(文件指针);while(ch!=EOF){putchar(ch);ch=fgetc(文件指针);}10.3文件的读写注意:EOF不是可输出字符,因此不能在屏幕上显示。由于字符的ASCII码不可能出现-1,因此EOF定义为-1是合适的。当读入的字符值等于-1(即EOF)时,表示读入的已不是正常的字符而是文件结束符。但以上只使用于读文本文件的情况。现在ANSIC已允许用缓冲文件系统处理二进制文件,而读入某一个字节中的二进制数据的值有可能是-1,而这又恰好是EOF的值。这就出现了需要读入有用数据而却被处理为“文件结束”的情况。为了解决这个问题,ANSIC提供一个feof函数来判断文件是否真的结束。feof(fp)用来测试fp所指向的文件当前状态是否“文件结束”。如果是文件结束,函数feof(fp)的值为1(真),否则为0(假)。如果读入一个二进制文件中的数据,可以用
while(!feof(fp)){c=fgetc(fp);…}2.fputc()函数把一个字符写到磁盘文件上去,其格式如下:fputc(字符,文件指针);例如向文件指针fp所指的文件写入字符‘c’的语句是:fputc(‘c’,fp);10.3文件的读写如果函数调用成功,则返回写入的字符;如果失败,则返回EOF(-1)。下面的程序实现了复制文件的功能,源文件为c:\tc\abc.txt,目标文件为c:\tc\xyz.txt。例10.1程序举例#include<stdio.h>main(){FILE*fp1,*fp2;/*声明两个文件指针,分别用于源文件和目标文件*/charc;if((fp1=fopen("abc.txt","r"))==NULL||(fp2=fopen("xyz.txt","w+"))==NULL)/*同时打开源文件和目标文件,分别为只读方式和新建文件方式*/printf("FileOpenError\n");else{while((c=fgetc(fp1))!=EOF)/*循环从源文件读入字符,遇到文件结束符停止*/10.3文件的读写fputc(c,fp2);fclose(fp1);fclose(fp2);}system("cls");printf("abc.txt:\n");system("typeabc.txt");/*调用DOS命令输出源文件内容*/printf("\n\nxyz.txt:\n");system("typexyz.txt");/*调用DOS命令输出目标文件内容*/}运行结果如下:10.3文件的读写10.3.2fgets()函数和fputs()函数 以字符为单位的fgetc()函数和fputc()函数一次只能读出或写入一个字符到文件中,显然处理大量数据时效率不高,以字符串为单位的fgets()函数和fputs()函数可以一次从文件输入或向文件输出一个字符串。1.fgets()函数fgets()是从文件而不是从标准输入设备取得字符串。其格式如下:fgets(字符串指针,字符个数,文件指针); 其中第一个参数“字符串指针”,即一个字符组名或指向字符的指针,用于存放读出的字符串;第二个参数指明读出多少个字符,是一个整型数;第三个参数即目标文件的文件指针。
fgets()在遇到换行符或文件结束符时,即使已读取得字符数小于参数中指定的数量也会自动停止。如程序设计者已经知道abc.txt文件不大于100个字节,调用fgets()函数的第二个参数为100,使得整个文件被一次读取。若abc.txt文件大于100字节,则后面的内容没有被读取。如果fgets()读取到文件结束符,将会返回一个NULL值。可以据此判断是否到达文件尾部,使用循环语句读出整个文件。若目标文件的结构不清晰,一般使用fgetc()函数逐个字符读取,逐个处理。在预先知道目标文件结构的情况下,使用fgets()函数能提高效率。10.3文件的读写2.fputs()函数fputs()函数用于向文件写入字符串,它的使用格式如下:
fputs(字符串,文件指针); 第一个参数可以是一个字符串,也可以是一个字符数组或指向字符的指针;第二个参数是文件指针。例如:charc[100];char*s;fputs(“Hello”,fp);/*将字符串“Hello”写到fp所指文件中*/fputs(*s,fp);/*将字符指针s所指的字符串写到fp所指文件中*/fputs(c,fp);/*将字符数组c的内容写到fp所指文件中*/下面的程序利用fgets()函数和fputs()函数实现了复制文件的功能,源文件为abc.txt,目标文件为xyz.txt。10.3文件的读写例10.2程序举例#include<stdio.h>main(){FILE*fp1,*fp2;chars[100];if((fp1=fopen("abc.txt","r"))==NULL||(fp2=fopen("xyz.txt","w+"))==NULL)printf("FileOpenError\n");else{fgets(s,100,fp1);fputs(s,fp2);fclose(fp1);fclose(fp2);}10.3文件的读写system("cls");printf("abc.txt:\n");system("typeabc.txt");printf("\n\nxyz.txt:\n");system("typexyz.txt");}运行结果:10.3文件的读写10.3.3fwrite()函数和fread()函数这类操作,以二进制方式读写文件。在某些情况下不合适使用文本方式读写文件,在这种情况下,选择使用二进制方式读写文件。如果采用二进制读写方式,那么数据在文件中的占用空间的大小与在内存中完全一致。二进制读写方式克服了文本读写方式的缺点,能够获得更高的时间、空间效率和安全性。在内存中连续的若干长度的,表示特定一个或多个数据的二进制数据称为二进制数据块。1.fwrite()函数使用fwrite()函数可以将内存中的二进制数据以数据块为单位写入指定的二进制文件中,其格式如下:
fwrite(内存起始地址,数据块长度,重复次数,目标文件指针);例:FILE*fp;10.3文件的读写inta=12345;…/*以二进制方式打开文件*/fwrite(&a,2,1,fp);上面的语句调用fwrite()函数将整型变量a的值输出到文件指针fp所指的文件中。第一个参数表达式“&a”的值即变量a的起始地址;第二个参数是整型变量a的长度,应为2个字节(16位);第三个参数1表示只进行一次输出操作;最后一个参数指出输出目标文件是当前文件指针fp所指的文件。如果不确切知道待输出数据的长度,可以使用sizeof()函数取得。如上例的fwrite()函数可以写为:fwrite(&a,sizeof(a),1,fp);/*使用sizeof()函数取得输出变量a的长度*/如果fwrite调用成功,则函数返回值为count的值,即输入或输出数据项的完整个数。使用fwrite()函数也可以整个数组或结构体以二进制方式写入文件中。10.3文件的读写例:FILE*fp;floatx[10];…/*以二进制形式打开文件*/fwrite(x,sizeof(float)*10,1,fp);/*将浮点型数值x的所有元素都写入fp所指的二进制文件中*/
2.fread()函数 与写二进制数据块函数fwrite()对应,fread()用于读取已经写入到二进制文件的二进制数据块。fread()函数使用格式:
fread(内存起始地址,数据块长度,重复次数,目标文件指针);
fread()函数中三个参数的意义与fwrite()函数中对参数的意义相似,只是两者传输数据的方向不同。fread()函数返回一个整型数值。如果所有数据都成功读取,fread()函数返回第三个参数的值;如果读取数据出错或遇到文件结束符,fread()函数返回成功读取的数据块的数量,即成功读取了多少个指定长度(由第二个参数决定)的数据块。10.3文件的读写例:FILE*fp;inta;…/*打开文件*/fread(&a,sizeof(int),1,fp);上面的语句调用了fread()函数,将文件指针fp所指的二进制文件中的sizeof(int)个字节的数据存入整型变量a的内存空间中。使用fread()函数需要注意一点:务必保证不损害内存中未知区域的数据。下面是一个错误的例子:FILE*fp;charname[10];…/*以二进制形式打开文件*/fread(name,1,11,fp);/*错误!*/
这条语句从文件指针fp所指的二进制文件中读取11个字符的数据,已经超出了name数组的范围。10.3文件的读写例10.3现有一个关于学生信息的磁盘文件file1,请把该文件存入另一个文件file2中。 实际上,这个题目的要求是编写一个程序,实现文件复制功能。 其程序如下:#include<stdio.h>structstu/*宏定义*/{intid;/*结构体成员*/charname[20];intage;};main()/*主函数*/{structstustu1;/*定义结构体变量*/intnFILE*in,*out;10.3文件的读写if((in=fopen("file1.txt","r"))==NULL||(out=fopen("file2.txt","w+"))==NULL)printf("FileOpenError\n");/*打开文件*/else{while(fread(&stu1,sizeof(structstu),1,in)==1)/*读文件*/fwrite(&stu1,sizeof(structstu),1,out);/*写文件*/fclose(in);/*关闭文件*/fclose(out);/*关闭文件*/}}该函数每次以二进制形式从file1文件中读取一个结构类型(stu)的数据,然后把该数据写到file2文件中。当fread()函数的返回值不等于1时,就意味着读出错或读结束,此时结束循环。关于代码的详细情况,请参见代码中的注释10.3文件的读写10.3.4fscanf()函数和fprintf()函数 下面介绍具有更强大的功能的文件格式化输入、输出函数:fscanf函数和fprintf()函数。1)fscanf()函数
fscanf()函数的功能与使用方法与scanf()函数基本相同,只是fscanf()函数获取数据的来源文件,而不是键盘。fscanf()函数使用格式:fscanf(文件指针,输入内容,输入项);fscanf()函数的第一个参数是一个文件指针,指出从哪个文件输入格式化数据。除此外,fscanf()函数与scanf()函数在使用上没有差别。例:FILE*fp;intd;charc;10.3文件的读写…/*打开文件*/fscanf(fp,“%d%c”,&d,&c);/*从文件输入数据*/上面的fscanf()函数从文件指针fp所指文件输入一个整型数和一个字符,并保存到整型变量d和字符变量c中。两项数据以空格分隔。2)fprintf()函数fprintf()函数与常用的printf()函数很类似。fprintf函数使用格式:fprintf(文件指针,输出内容,输出项);fprintf()函数的第一个参数指明输出的目标文件,其他参数的格式与printf()函数一致。例:FILE*fp;…/*打开文件*/intd;fprintf(fp,”%d\n”,d);/*输出数据到文件*/10.3文件的读写上面的语句使用fprintf()函数向文件指针fp所指的文件输出一个整型数据和一个回车符。使用fscanf()函数和fprintf()函数时,由于在输入时要将ASCII码转换为二进制形式,在输出时又要将二进制形式转换成字符,花时间较多。用fscanf()函数和fprintf()函数对磁盘文件读写,使用方便,但在内存与磁盘频繁交换数据的情况下,最好不用fprintf和fscanf函数,而用fread和fwrite函数。10.4文件的定位在对文件进行操作时,不一定始终都是从文件的开始位置进行操作的,因此,对文件的定位非常重要。本节将介绍一系列文件定位函数。1.fseek()函数fseek()函数可以实现改变文件的位置指针。fseek()函数的格式如下:fseek(文件指针,偏移量,基点);文件指针无需详细说明;偏移量表示以基点为起始位置,向前或向后移动的距离,以字节为单位,数据类型为长整形;基点有三个取值,意义:0——文件开头,1——文件当前位置,2——文件末尾。例如:FILE*FP;…/*打开文件*/fseek(fp,5L,0);/*将位置指针移到距文件开头5个字节处*/fseek(fp,-10L,0);/*使位置指针相对文件当前位置向前移动10个字节处*/fseek(fp,-40L,0);/*使位置指针移到距文件尾部40个字节处*/第二个参数是长整型数据,因而要在数值后加“L”表示这是一个长整型数。如果成功移动,fseek()将返回0值,否则返回非0值。10.4文件的定位2.rewind()函数调用函数能使位置指针重新返回文件的开头。此函数没有返回值。rewind()函数的格式如下:rewind(文件指针);例如:FILE*fp;…/*打开文件*
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 课题申报参考:跨文化主义范式下的19世纪中法艺术交流研究
- 历史地质资料对现代山区桥梁设计的借鉴价值
- 校园内消防安全培训与应急救援队伍建设
- 如何以医疗技术提升患者满意度与就医体验
- 2025年冀教版选择性必修3化学上册月考试卷含答案
- 2025年外研版2024八年级地理下册月考试卷含答案
- 2025年新科版八年级地理上册阶段测试试卷含答案
- 2025年苏教版必修1地理上册阶段测试试卷含答案
- 2025年浙教版九年级历史上册阶段测试试卷
- 2024年北师大新版必修3地理上册阶段测试试卷含答案
- 安徽省蚌埠市2025届高三上学期第一次教学质量检查考试(1月)数学试题(蚌埠一模)(含答案)
- 【探迹科技】2024知识产权行业发展趋势报告-从工业轰鸣到数智浪潮知识产权成为竞争市场的“矛与盾”
- 《中国政法大学》课件
- GB/T 35270-2024婴幼儿背带(袋)
- 辽宁省沈阳名校2025届高三第一次模拟考试英语试卷含解析
- 2024-2025学年高二上学期期末数学试卷(新题型:19题)(基础篇)(含答案)
- 2022版艺术新课标解读心得(课件)小学美术
- Profinet(S523-FANUC)发那科通讯设置
- 第三章-自然语言的处理(共152张课件)
- 医学教程 常见化疗药物归纳
- 行政事业单位国有资产管理办法
评论
0/150
提交评论