专升本C语言——第十章
admin
2024-04-14 07:36:22
0

对文件的输入输出

什么是文件?

文件有不同的类型,在程序设计中,主要用到两种文件

程序文件

包括源程序文件(后缀为.c)、目标文件(后缀为.obj)、可执行文件(后缀为.exe)等。这种文件的内容是程序代码

数据文件

常常需要将一些数据(运行的最终结果或中间数据)输出到磁盘上保存起来,以后需要时再从磁盘中输入到计算机内存,这就要用到磁盘文件

文件是程序设计中的一个重要的概念,所谓”文件“一般指存储在外部介质上数据的集合

文件由运行环境(即操作系统)进行统一管理的

C的数据文件由一连串的字符(或字节)组成,而不考虑行的界限,两行数据间不会自动加分隔符,对文件的存取是以字符(字节)为单位的。输入输出数据流的开始和结束仅受程序控制而不受物理符号(如回车换行符)控制,这就增加了处理的灵活性。这种文件称为流式文件。

文件名

一个文件要有唯一的文件标识,以便用户识别和引用。文件标识包括3部分:文件路径;文件名主干;文件后缀

D:\\CC\temp\file1.dat  //表示file1.dat文件存放在D盘中CC目录下的temp子目录下面

文件标识符常被称为文件名,此时所称的文件名包括上面的3部分。

文件名主干的命名规则遵循标识符的命名规则

后缀用来表示文件的性质,一般不超过3个字母(如:doc)

文件的分类

数据文件可分为ASCLL文件和二进制文件

数据在内存中是以二进制形式存储的,如果不加转换地输出到外存,就是二进制文件,可以认为它就是存储在内存的数据的映像,所以也称之为映像文件。如果要求在外存上以ASCLL代码形式存储,则需要在存储前进行转换,ASCLL文件又称文本文件,每个字节放一个字符的ASCLL代码

文件缓存区

所谓文件缓存系统是指系统自动地在内存区为程序中每一个正在使用的文件开辟一个文化缓冲区。从内存向磁盘输出数据必须先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘去。如果从磁盘向计算机读入数据,则一次从磁盘文件将一批数据输到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(给程序变量)。

文件类型指针

缓存文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。

定义FILE类型的变量

FILE F1;//定义了一个结构体变量f1,用它存放一个文件的有关信息

定义一个指向文件型数据的指针变量

FILE* fp;//定义fp是一个指向FILE类型数据的指针变量,可以使fp指向一个文件信息区(是一个结构体变量),通过该文件信息区中的信息能够访问该文件

通常将这种指向文件信息区的指针变量简称为指向文件的指针变量

打开和关闭文件

所谓打开是指为文件建立相应的信息区(用来存放有关文件的信息)和文件缓冲区(用来暂时存放输入输出的数据)

所谓关闭是指撤销文件信息区和文件缓冲区,使文件指针变量不再指向该文件,显然就无法进行对文件的读写了

用fopen函数打开数据文件

fopen 函数的调用方式为

fopen(文件名,使用文件方式);
//例如:
fopen("al","r");//表示打开名字为“al”的文件,使用文件方式为“读入”//fopen的返回值指向al文件的指针(即al文件信息区的起始地址)通常将fopen函数的返回值赋给一个指向文件的指针变量
FILE* fp;			//定义一个指向文件的指针变量fp
fp=fopen("al","r");	//将fopen函数的返回值赋给指针变量fp
文件使用方式含义如果指定的文件不存在
“r“(只读)为了输入数据,打开一个已存在的文本文件出错
”w”(只写)为了输出数据,打开一个文本文件建立新文件
“a”(追写)向文本文件添加数据出错
“rb”(只读)为了输入数据,打开一个二进制文件出错
”wb”(只写)为了输出数据,打开一个二进制文件建立新文件
“ab”(追加)向二进制文件尾添加数据出错
“r+”(读写)为了读和写,打开一个文本文件出错
“w+”(读写)为了读和写,建立一个新的文本文件建立新文件
“a+”(读写)为了读和写,打开一个文本文件出错
“rb+”(读写)为了读和写,打开一个二进制文件出错
“wb+”(读写)为了读和写,建立一个新的二进制文件建立新文件
“ab+”(读写)为读写打开一个二进制文件出错

用fclose函数关闭数据文件

关闭就是撤销文件信息区和文件缓冲区,使文件指针变量不再指向该文件,也就是文件指针变量与文件“挂钩”,此后不能再通过该指针对原来与其相联系的文件进行读写操作,除非再次打开,使该指针变量重新指向该文件

关闭文件用fclose函数。fclose函数调用的一般形式为

fclose(文件指针);
//例如:
fclose(fp);

前面曾把打开文件(用fopen函数)时函数返回的指针赋给了fp,现在把fp指向的文件关闭,此后不再指向该文件

如果不关闭文件将会丢失数据,因为,在向文件写数据时,是先将数据输出到缓冲区,待缓冲区充满后才正式输出给文件。如果当数据未充满缓冲区就程序结束运行,就有可能使缓冲区中的数据丢失。要用fclose函数关闭文件,先把缓冲区中的数据输出到磁盘文件,然后才撤销文件缓冲区。有的编译系统在程序结束前会自动先将缓冲区中的数据写到文件。从而避免了这个问题,但还是应当养成在程序终止之前关闭所有文件的习惯

fclose函数也带回一个值,当成功地执行了关闭操作,则返回值为0;否则返回EOF(-1)

顺序读写数据文件

怎样向文件读写字符

读写一个字符的函数

函数名调用形式功能返回值
fgetcfgetc(fp)从fp指向的文件读入一个字符读成功,带回所读的字符,失败则返回文件结束标志EOF(-1)
fputcfputc(ch,fp)把字符ch写到文件指针变量fp所指的文件中输出成功,返回值就是输出的字符;输出失败,则返回EOF(-1)

说明:fgetc的第1个字母f代表文件(file),中间的get表示“获取”,最后一个字母c表示字符(character),fgetc的含义很清楚:文件读取一个字符。fputc也类似

//从键盘输入一些字符,逐个把它们送到磁盘上去,直到用户输入一个"#"为止
//解题思路:用fgetc函数从键盘逐个输入字符,然后用fputc函数写到磁盘文件即可
#include
#include
int main()
{FILE* fp;char ch, filename[10];printf("请输入所用的文件名:");scanf("%s",filename);if ((fp = fopen(filename,"w")) == NULL)		//打开输出文件并使fp指向此文件{printf("无法打开此文件\n");				//如果打开时错误,就输出“打不开”的信息exit(0);								//终止循环}ch = getchar();								//用来接受最后输入的回车符printf("请输入一个准备存储到磁盘的字符串(以#结束):");ch = getchar();								//接收从键盘输入的第一个字符while (ch != '#')							//当输入'#'时结束循环{fputc(ch, fp);							//向键盘文件出一个字符putchar(ch);							//将输出的字符显示在屏幕上ch = getchar();							//再接受从键盘输入的一个字符}fclose(fp);									//关闭文件putchar(10);								//向屏幕输出一个换行符return 0;
}
//将一个磁盘文件中的信息赋值到另一个磁盘文件中,今要求将上列建立的file.dat文件中的内容赋值到另一个磁盘文件file2.dat中
//解题思路:处理此问题的算法是,从file1.dat文件中逐个读入字符,然后逐个输出到file2.dat中
#include
#include
int main()
{FILE* in, * out; //定义指向FILE类型文件的指针变量char ch, infile[10], outfile[10];//定义两个字符数组,分别存放两个数据文件名printf("输入读入文件的名字:");scanf("%s", infile);//输入一个输入文件的名字printf("输人输出文件的名字:");scanf("%s", outfile);//输入一个输出文件的名字if ((in = fopen(infile, "r")) == NULL)//打开输入文件{printf("无法打开此文件\n");exit(0);}if ((out = fopen(outfile, "w")) == NULL)//打开输出文件{printf("无法打开此文件\n");exit(0);}while (!feof(in))//如果未遇到输入文件的结束标志{ch = fgetc(in);//从输入文件读入一个字符,暂放在变量ch中fputc(ch, out);//从ch写到输出屏幕上putchar(ch);//将ch显示在屏幕上}putchar(10);//显示完全部字符后换行fclose(in);//关闭输入文件fclose(out);//关闭输出文件return 0;
}

读写一个字符串的函数

函数名调用形式功能返回值
fgetsfgets(str,n,fp)从fp指向的文件读入一个长度为(n-1)的字符串,存放到字符数组str中读成功,返回地址str,失败则返回NULL
fputsfputs(str,fp)把str所指向的字符串写到文件指针变量fp所指向的文件中输出成功,返回0;否则返回非0值

fgets中最后一个字符s表示字符串(string)。fgets的含义是从文件读取一个字符串

说明:

fgets函数的函数原型为

char *fgets(char *str,int n,FILE *fp)//其作用是从文件读入一个字符串,
//调用时可写成
fgets(str,n,fp);//实际上只从fp所指向的文件读入n-1个字符,然后在最后加'\0'字符

fputs函数的函数原型为

int fputs(char *str,FILE fp);//其作用是将str所指向的字符串输出到fp所指向的文件中
//调用时可写成
fputs("china",fp);//字符串末尾'\0'不输出,第一个参数可以是字符串常量、字符数组名或字符型指针

fgets和fputs这两个函数的功能类似于gets和puts函数,只是gets和puts以中终端为读写对象,而fgets和fputs函数以指定的文件作为读写对象

用格式化的方式读写文件

fprintf和fscanf函数

fprintf(文件指针,格式字符串,输出表列);
fscanf(文件指针,格式字符串,输入表列);
//例如:
fprintf(fp,"%d,%6.2f",i,f);//它的作用是将int型变量i和float变量f的值按%d和%6.2f的格式输出到fp指向的文件中

用二进制方式向文件读写一组数据

一般调用形式

fread(buffer,size,count,fp);
fwrite(buffer,size,count,fp);
  • buffer:是一个地址。对fread来说,它是用来存放从文件读入的数据的存储区的地址。对fwrite来说,是要把此地址开始的存储区中的数据向文件输出(以上指的是起始地址)
  • size:要读写的字节数
  • count:要读写多少个数据项(每个数据项长度为size)
  • fp: FILE类型指针
  • 在打开文件时用二进制文件,这样就可以用fread和fwrite函数读写任何类型的信息
fread(f,4,10,fp);//f是一个float类型数组名(代表数组首元素地址)这个函数从fp所指向的文件读入10个4个字节的数据,存储到数组f中

随机读写数据文件

文件位置标记及其定位

文件位置标记

为了对读写进行控制,系统为每个文件设置了一个文件读写位置标记(简称文件位置标记或文件标记),用来指示接下来要读写的下一个字符的位置

如果是顺序读文件,则每写完一个数据后,文件位置标记顺序向后移一个位置,然后在下一个执行写操作时把数据写入指针所指的位置。直到把全部数据写完,此时文件位置标记在最后一次数据之后

可以根据读写的需求,人为地移动文件位置标记的位置。文件位置标记可以向前移、向后移,移到文件头或文件尾,然后对该位置进行读写,显然这不是顺序读写了,而是随机读写

文件位置标记的定位

用rewind函数使文件位置标记指向文件开头

rewind函数的作用是使文件位置标记重新返回文件的开头,此函数没有返回值

fseek函数改变文件位置标记

fseek函数的调用形式为

fseek(文件类型指针,位移量,起始点)//起始点用0、1、2代替,0代表文件开始位置,1为当前位置,2为文件末尾位置

位移量指开始点为基点,向前移动的字节数,位移量应是long型数据(在数字的末尾加一个字母L,就表示是long型)

//fseek函数一般用于二进制文件
fseek(fp,100L,0);	//将文件位置标记向前移到离文件开头100个字节处
fseek(fp,50L,1);	//将文件位置标记向前移到离当前位置50个字节处
fseek(fp,-10L,2);	//将文件位置标记从文件末尾处向后退10个字节

用ftell函数测定文件位置标记的当前位置

ftell函数的作用是得到流式文件中文件位置标记的当前位置

由于文件中的文件位置标记经常移动,人们往往不容易知道其当前位置,所以常用ftell函数得到当前位置,用相对于文件开头的位移量来表示。如果调佣函数时出错(如不存在fp指向的文件),ftell函数返回值为-1L

i=ftell(fp);//变量i存放文件当前位置
if(i==-1L)printf("error\n");//如果调用函数时出错,输出"error"

相关内容

热门资讯

4家银行AIC现身存储巨头股东... 近日,资本市场热度颇高的两家存储巨头长鑫科技集团股份有限公司(以下简称“长鑫科技”)、长江存储控股股...
8元无限续杯、0元看电影、老字... 城市的烟火暖意,藏在亲民的消费场景里,也藏在老地标的新生蜕变中。粤汉码头火车旁新开竹林茶馆,8元就能...
2026年水利工程新趋势,这些... 随着全球气候变化和城市化进程的加速,水利工程在保障水资源供给、改善生态环境以及提升人民生活质量中的作...
原创 发... 这几年,身边越来越多人开始换一种活法:不急着买房,不执着“上车”,反而愿意把钱拿去租一套更舒服、更体...
小红书入场Skill分发,B站... 来源:界面新闻 文丨AI价值官 星野 编辑丨美圻 过去半年,Skill 这个词在AI圈的出现...
2026年福州企业门户网站建设... 本篇将回答的核心问题 在数字化转型加速的2026年,企业门户网站建设应遵循哪些核心评估标准,以确保投...
原创 今... 今日金价:2026年5月22日注意了!黄金或现历史类似回调走势 5月22日,金市又热闹起来了,咱们看...
雷军发布YU7 GT、YU7标... 5月21日,小米人车家全生态新品发布会在北京举办,小米集团创始人、董事长兼CEO雷军正式发布小米YU...
留神峪煤矿瓦斯爆炸事故发布会:... 昨晚,山西留神峪煤矿发生瓦斯爆炸,造成重大人员伤亡。今天,当地召开新闻发布会,现场全体默哀。会上介绍...
原创 修... 修复资产负债表,日本花了几十年。 自上世纪90年代初泡沫经济破裂后,日本陷入了长达三十年的通缩螺...
2026年小红书效果化种草白皮... 2026 年小红书正式迈入种草效果化时代,这是品牌追求预算确定性回报与平台升级为消费决策、用户信任场...
连续18年获“全国文化企业30... 南都讯 记者钟欣5月21日,第二十二届中国(深圳)国际文化产业博览交易会开幕。展会期间,光明日报社和...
荣耀确认IPO未终止!开放员工... 5月22日,荣耀因股改满一年未完成IPO,按约定正式开放员工持股退出通道。据《财闻》报道称,当日16...
易方达蓝筹精选有新变动:增聘2... 《每日经济新闻》记者获悉,继景顺长城、中欧等多家基金公司旗下百亿基金经理产品调整后,易方达基金也迎来...
光储龙头,又翻倍了 去年海外光储赛道最受关注的公司,毫无疑问是阳光电源,市值重回巅峰,风光无限。 但今年一季度业绩突然失...
中企出海报告在静安发布,七成受... 来源:滚动播报 (来源:上观新闻) 昨天,在上海静安举办的澳洲会计师公会出海论坛暨澳洲注册会计师颁...
京蒙协作延链强链 科右中旗牛产... 初夏时节,走进内蒙古华阳牛业科技集团有限公司屠宰加工车间,自动化生产线高效运转。作为京蒙协作产业帮扶...
原创 中... 最近发布了一份有关新一线城市魅力的榜单。榜单按照商业资源聚集度、城市枢纽性、城市人活跃度这五个方面来...
突然,全线跳水!超16万人爆仓 来源:宁波晚报 5月23日,被视作反映市场风险偏好指标的加密货币持续跳水。 截至发稿,比特币大跌3....
基民懵了!说好的科技行情,结果... 每经记者:叶峰 每经编辑:赵云 本周股指冲高回落,沪深两市股票型ETF和跨境型ETF合计净流出729...