author:Carlton
tag:C语言
topic:打开与关闭、顺序读写数据文件
time:2023 年 7 月 5 日
目录
打开与关闭文件
含义
打开:为文件建立相应的信息区(用来存放有关文件的信息)和文件缓冲区(用来暂时存放输入输出的数据),并建立文件指针与文件的指向关系
fopen函数
fopen(文件名,使用文件方式)
注:文件名包括文件路径,文件名主干和文件后缀,方便期间,以下只写文件名主干。在双引号里表示反斜杠"\"要反转义"\\"
e.g
fopen("a1","r");
用只读该文件的方式打开一个文本文件
函数返回值为指向该文件的文件指针,出错则返回空指针NULL
文件的使用方式
文件使用方式 | 含义 | 如果指定的文件不存在 |
r(只读) | 为了从文本向计算机输入数据,打开一个已存在的文本文件 | 出错 |
w(只写) | 为了从计算机向文件输出数据,打开一个文本文件 | 建立新文件 |
a(追加) | 向文本文件尾添加数据 | 出错 |
rb(只读) | 为了从文本向计算机输入数据,打开一个已存在的二进制文件 | 出错 |
wb(只读) | 为了从计算机向文件输出数据,打开一个二进制文件 | 建立新文件 |
ab(追加) | 向二进制文件尾添加数据 | 出错 |
r+(读写) | 为了读和写,打开一个新的文本文件 | 出错 |
w+(读写) | 为了读和写,建立一个新的文本文件 | 建立新文件 |
a+(读写) | 为了读和写,打开一个新的文本文件 | 出错 |
rb+(读写) | 为了读和写,打开一个新的二进制文件 | 出错 |
wb+(读写) | 为了读和写,建立一个新的二进制文件 | 建立新文件 |
ab+ | 为了读和写,打开一个新的二进制文件 | 出错 |
注意:
①用w方式打开的文件若已存在,则会被删除后新建一个用于从计算机输入数据到此文件中。
②用a方式打开的文件不会被删除,打开后文件读写位置标记移到文尾
③对文件使用是视作处理文本文件还是二进制文件的区别在于对换行的处理
文本文件在从终端读入数据时,遇到“\n”转换为"\r\n"读入(Windows系统需要“回车”和“换行”两个字符来实现换行),向终端输出数据时,将“\r\n”转换为"\n"
二进制文件则不需要此类转换
标准流文件 | 文件指针变量 | 含义 |
标准输入流 | stdin | 从终端的输入 |
标准输出流 | stdout | 向终端的输出 |
标准出错输出流 | stderr | 出错时将出错信息发送到终端 |
检错的方式
常使用下面的方式打开一个文件:
#include<stdio.h>
#include<stdlib.h> //exit()函数需要调用stdlib.h文件
File *fp;
if((fp=fopen("file1","r"))==NULL)
{
printf("cannot open this file\n");
exit(0); //关闭程序,需要调用stdlib.h文件
}
fclose函数
fclose(文件指针)
关闭其指针指向的文件,并撤销其指向关系
e.g
fclose(fp);
将fp指向的文件关闭后,fp也不再指向该文件。
函数执行成功的返回值为0,否则返回EOF(end of file,在stdio.h头文件被宏定义为-1)
应在程序结束运行前关闭文件,防止数据丢失。例如向文件中写入数据时,如果缓冲区还未填满则数据还不会正式输出给文件,若停止运行程序则该缓冲区里的数据将会丢失。
顺序读写数据文件
对顺序读写来说,对文件读写数据的顺序和数据在文件中的物理顺序是一致的。
相关的函数
终止程序运行函数
exit();
终止运行程序,需要调用stdlib.h文件
文件末尾判断函数
feof();
括号内放入文件指针,用于检测文件尾标志是否已被读取过。
若已被读出,表示文件已结束,返回值为真(1),否则为假(0)
文件读取的过程:
访问磁盘文件时,是逐个字符(字节)进行,系统使用“文件读写位置标记”来表示当前所访问的位置。
开始时指向第1个字节,每访问完一个字节后,当前读写位置自动指向下一个字节。
因此为了知道对文件的读写是否完成,只须看文件读写位置是否移到末尾
文件所有有效字符后有一个文件尾标志,用标识符EOF(end of file)表示,在stdio.h头文件中被宏定义为-1
所以读完全部字符后,文件读写标记就指向最后一个有效字符后面,即指向了文件尾标志,再执行读取操作,则会读出-1(是一种处理方式,不存在存放了数值-1的”结束字节“)
判断文件是否结束可以有两种方式
①使用feof函数
②判断读写的字符是否为-1或EOF
文本读写函数
读写字符数据
函数名 | 调用形式 | 功能 | 返回值 |
fgetc | fgetc(fp) | 从fp指向的文件读入一个字符 | 读成功,带回所读的字符,失败则返回文件结束标志EOF(即-1) |
fputc | fputc(ch,fp) | 把字符ch写到文件指针变量fp所指向的文件中 | 输出成功,返回值就是输出的字符,输出失败,则返回EOF(即-1) |
读写字符串数据
函数名 | 调用形式 | 功能 | 返回值 |
fgets | fgets(str,n,fp) | 从fp指向的文件读入一个长度为(n-1)的字符串,存放到字符数组str中 | 读成功,返回地址str,失败则返回NULL |
fputs | fputs(str,fp) | 把str所指向的字符串写到文件指针变量fp所指向的文件中 | 输出成功,返回0;否则返回-1 |
使用fgets函数时,实际上只读入n-1个字符,在最后加入'\0'字符。若在读完n-1个字符之前遇到换行符“\n”或文件结束符EOF,读入即结束,但将“\n”也作为一个字符读入。
使用fputs函数时,第一个参数可以是字符串常量,字符数组名或字符型指针。字符串末尾的'\0'不输出给文件。
格式化读写文本文件
我们不仅有对字符型数据处理的需求,还需要对各种类型的数据进行输入输出,因此使用格式化读写文本文件。
fprintf (文件指针,格式字符串,输出表列);
fscanf (文件指针,格式字符串,输入表列);
读写的对象是文本文件,每一次磁盘文件和内存之间的输入输出都会进行ASCII码和二进制形式的转换
二进制读写函数
在程序中不仅需要一次输入输出一个数据,而且常常需要一次输入输出一组数据(数据块)(如数组或结构体变量的值),此时内存与磁盘需要频繁交换数据,我们用专门的函数来进行二进制的读写。
fread (buffer,size,count,fp);
fwrite (buffer,size,count,fp);
buffer:是一个“文件之外”的数据地址
对fread而言是用来存放从文件读入的数据的存储区的地址;对fwrite来说是要把从此地址开始的存储区中的数据向文件输出。
size:要读写的字节数
count:要读写多少个数据项(每个数据项长度为size)
fp:FILE类型指针
函数类型均为int型,若执行成功返回值为形参count的值,即输入或输出数据项的个数
数据输入输出变化状况
情景:
①从键盘敲入数据,存储数据给某个数组,再将数组存放的数据存入给磁盘文件。
②将磁盘文件的数据读出给某个数组,将数组得到的数据打印在显示屏上
差异对比与思考总结
终端与文件
对象不同
主体不同,出发点、落脚点不同。
例如我们用printf(),scanf()函数是视终端为主体,向终端输出打印数据,从终端扫描读入数据。用gets,puts函数也类似,从终端获取得到字符串,向终端放置输出字符串。
fscanf,fprintf,fread,fwrite则是以文件为主体(file),其功能分别为从文本文件扫描读出数据,向文本文件打印输出数据,从二进制文件读出数据,向二进制文件写入数据。
文本和二进制
①数据的存储方式
文本方式:数据以字符方式(ASCII代码)存储到文件中,此类数据便于阅读
二进制方式:数据按在内存的存储状态(二进制形式)原封不动地复制到文件
②文件的分类
文本文件(ASCII文件):文件中全部为ASCII字符
二进制文件:按二进制方式把内存中的数据复制到文件的文件
③文件的打开方式
文本方式:不带b的方式,读写文件时对换行符进行转换
二进制方式:带b的方式,读写文件时对换行符不进行转换
④文件读写函数
文本读写函数:用来向文本文件读写字符数据的函数
如fgetc,fgets,fputc,fputs,fscanf,fprintf等
二进制读写函数:用来向二进制文件读写二进制数据的函数
如getw(从文件读出一个整数),putw(向文件输入一个“字”(word))//不甚熟悉,似乎与二进制,数据流,“字”有关,fread,fwrite等
欢迎“指针”与分享,谢谢!