学习

C语言——文件操作

什么是文件?

文件有不同类型,在程序设计中,主要用到两种文件
1.1程序文件,包括源程序文件(后缀为.c),目标文件(后缀为.obj),可执行文件(后缀为.exe)等,这种文件的内容是程序代码

1.2数据文件,文件的内容不是程序,而是供程序运行时读写的数据,如在程序运行过程中输出到磁盘的数据,或者在程序运行过程中供读入的数据

2.不必去区分各种输入输出设备之间的区别,操作系统把各种设备都统一作为文件来处理

3.所谓'文件'一般指存储在外部介质上数据的集合,一批数据是以文件的形式存放在外部介质(如磁盘)上的,操作系统是以文件为单位对数据进行管理的,也就是说,如果是想找存放在外部介质上的数据,必须先按照文件名找到所指定的文件,然后再从该文件中读取数据,要向外部介质上存储数据也必须先建立一个文件,才能向它输出数据。

4.数据流?
输入输出是数据传送的过程,数据如流水一样从一处流向另一处,因此常将输入输出的形象第称为流,即数据流

4.1流表示了信息从源到目的段的流动,在输入操作时,数据从文件流向计算机内存,在输出操作时,数据从计算机流向文件,文件是由操作系统进行统一管理的

5.C语言把文件看做成一个字符(或字节)序列,即由一个一个字符(或字节)的数据顺序组成,一个输入输出流就是应该字符流或者字节流(内容为二进制数据)

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

什么是文件名?

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

1.2 文件路径表示文件在外部存储设备中的位置

例如:D:\cc\temp\filel.dat
D:\cc\temp ->文件路径   filel->文件名主干  dat->文件后缀

2.文件标识常被称为文件名,文件名主干的命名规则遵循标识符的命名规则,后缀用来表示文件的性质

文件的分类

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

2.一个数据在磁盘上怎样存储?
2.1字符一律以ASCLL形式存储,数值型数据即可以用ASCLL形式存储,也可以用二进制形式存储

3.用ASCLL码形式输出时字节与字符一一对应,一个字节代表一个字符,因而便于对字符进行逐个处理,也便于输出字符,但一般占存储空间较多,而且要花费转换时间(二进制形式与ASCLL码间的转换)用二进制形式输出数值,可以节省外存空间,和转换时间,把内存中的存储单元中的内容原封不动地输出到磁盘(或其他外部介质)上,以便在需要时再输入到内存,一般用二进制文件比较方便。

文件缓冲区

1.ANSI C标准采用“缓冲文件系统”处理数据文件

2.什么是缓冲文件系统?
所谓缓冲文件系统是指系统自动地在内存区为程序中每一个正在使用的文件开辟一个文件缓冲区。从内存向磁盘输出数据必须先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘去,如果从磁盘向计算机读入数据,则一次从磁盘文件将一批数据输入到内存缓冲区(充满缓冲区)然后再从缓冲区逐个地将数据送到程序数据区(给程序变量) 这样做是为了节省存取时间,提高效率,缓冲区的大小由各个具体的C编译系统确定

注意点:
1.每一个文件在内存中只有一个缓冲区,在向文件输出数据时,它就作为输出缓冲区,再从文件输入数据时,
它就作为输入缓冲区

文件类型指针

1.缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。每个被使用的文件都在内存中
开辟一个相应的文件信息区,用来存放文件的有关信息(如文件的名字,文件状态及文件当前位置等)
这些信息是保存在一个结构体变量中的,该结构体类型是由系统声明的取名为FILE,
例如:有一种C编译环境提供的stdio.h头文件中有以下的文件类型声明

typedef struct {
    short level;            //缓冲区“满”或“空”的程度
    unsigned flags;         //文件状态标志
    char fd;                //文件描述符
    unsigned char hold;     //如缓冲区无内容不读取字符
    short bsize;            //缓冲区大小
    unsigned char *buffer;  //数据缓冲区的位置
    unsigned char *curp;    //文件位置标记指针当前的指向
    unsigned istemp;        //临时文件指示器
    short token;            //用于有效性检查
}FILE;

2.不同的C编译系统的FILE类型包含的内容不完全相同,但大同小异。对以上结构体中的成员及其含义
不可深究,只须知道其中存放文件的有关信息即可,
可以看到:FILE是以上结构体类型自己命名的类型名称FILE与上面的结构体类型等价

2.1以上声明的FILE结构体类型的信息包含在头文件中“stdio.h”中,程序中可以直接用FILE类型名定义变量。
每一个FILE类型变量对应一个文件的信息区,在其中存放该文件的有关信息。
列如:可以定义以下FILE类型的变量:

FILE f1;

以上定义了一个结构体变量fl,用它来存放一个文件的有关信息。这些信息是在打开一个文件时由系统根据文件
的情况自动放入的,在读写文件时需要用到这些信息,也会修改某些信息。例如在读一个字符后,文件信息区中的
位置标记指针的指向就要改变。

3.一般不定义FILE类型的变量命名,也就是不通过变量的名字来引用这些变量,而是设置一个指向 FILE类型变量的指针变量,
然后通过它来引用这些FILE类型变量。这样使用

4.下面定义一个指向文件型数据的指针变量:

FILE *fp;

定义fp是一个指向FILE类型数据的指针变量。可以使fp指向某一个文件的文件信息区(是一个结构体变量),
通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联的文件。
如果有n个文件,应设n个指针变量,分别指向n个FILE类型变量,以实现对n个文件的访问

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

注意点:指向文件的指针变量并不是指向外部介质上的数据文件的开头,而是指向内存中的文件信息区的开头

文件使用方式

C语言——文件操作

打开与关闭文件

1.对文件读写之前应该“打开”该文件,在使用结束后应“关闭”该文件。“打开”和“关闭”是形象的说法好像打开门才能进房子,关上门就无法进入一样,实际上,所谓“打开”是指为文件建立相应的信息区(用来存放有关文件的信息)和文件缓冲区(用来暂时存放输入输出的数据)

2.在编写程序时,在打开文件的同时,一般都指定一个指针变量指向该文件,也就是建立起指针变量与文件之间的联系,这样就可以通过该指针变量对文件进行读写了,所谓“关闭”是指撤销文件信息区和文件缓冲区,使文件指针变量不再指向该文件,显然就无法进行对文件的读写了

1.1用fopen函数打开数据文件
ANSI C规定了用标准输入输出函数fopen来实现打开文件
fopen函数的调用方式为
fopen(文件名,使用文件方式);
例如:fopen("a1","r");

表示要打开名字为a1的文件,使用文件方式为"读入"(r代表read,即读入)。

1.2.fopen函数的返回值是指向a1文件的指针(即a1文件信息区的起始地址)。通常将fopen函数的返回值赋给一个指向文件的指针变量

例如: FILE *fp;           //定义一个指向文件的指针变量fp
fp = fopen("a1","r");   //将fopen函数的返回值赋给指针变量fp

这样fp就和文件a1相联系了,或者说,fp指向了a1文件。可以看出,再打开一个文件时,
通知编译系统3个信息:
1.需要打开的文件的名字,也就是准备访问的文件的名字;
2.使用文件的方式("读"还是"写");
3.让哪一个指针变量指向被打开的文件

2.1用fclose函数关闭数据文件
在使用完一个文件后应该关闭它,以防止它再被误用。“关闭”就是撤销文件信息区和文件缓冲区
是文件指针变量不再指向该文件,也就是文件指针变量与文件“脱钩”,此后不能在通过该指针对原来
的其相联系的文件进行读写操作,除非再次打开,使该指针变量重新指向该文件

2.2  fclose函数调用的一般形式
fclose(文件指针);
例如:fclose(fp);

2.3如果不关闭文件就结束程序的运行将会丢失数据,因为,在向文件写数据时,是先将数据输出到缓冲区,待缓冲区充满后
才正式输出文件,如果当数据未充满缓冲区时,程序结束运行,就有可能造成数据丢失,

2.4用fclose函数关闭文件时,先把缓冲区中的数据输出到磁盘文件,然后才撤销文件信息区,有的编译系统自动将缓冲区
中的数据写到文件,从而避免了这个问题,但是应当养成在程序终止之前关闭所有文件的习惯

2.5fclose函数也带回一个值,当成功地执行了关闭操作,则返回值为0;否则返回EOF(-1)
代码展示:
C语言——文件操作

顺序读写数据文件

1.怎么向文件读写字符

1.1  fgetc(fp) 
功能:从fp指向的文件读入一个字符,
返回值:读成功,带回所读的字符,失败则返回文件结束标志EOF(-1)
1.2  fputc(ch,fp)
功能:把字符ch写到文件指针变量fp所指向的文件中
返回值:输出成功,返回值就是输出的字符,输出失败,则返回EOF(-1)

代码展示:
C语言——文件操作
C语言——文件操作

怎样向文件读写一个字符串

1.C语言允许通过函数fgets和fputs一次读写一个字符串

列如: fgets(str,n,fp);
作用:是从fp指向的文件中读入一个长度为n-1的字符串,并在最后加一个'\0'字符,
然后把这n个字符存放的字符数组str中

2.fgets函数:

调用形式: fgets(str,n,fp)
功能:从fp指向的文件读入一个长度为(n-1)的字符串,存放到字符数组str中
返回值:读成功,返回地址str,失败则返回NULL

3.fputs函数:

调用形式: fputs(str,fp)
功能:把str所指向的字符串写到文件指针变量fp所指向的文件中
返回值:读成功,返回0,否则返回非0值

注意点:
1.fgets(str,n,fp),n是要求得到的字符个数,但实际上只从fp所指向的文件中读入n-1个字符,然后在最后加一个'0'字符,这样就得到的字符串共有n个字符,把他们放到字符数组str中,如果在读完n-1个字符之前遇到换行符'n'或文件结束符EOF,读入即结束,但将所得到的的换行符"n"也作为一个字符读入

2.fputs("China",fp);把字符串"China"输出到fp指向的文件中,fputs函数中第一个参数利可以是字符串常量,字符数组名,字符型指针。字符串末尾的'0'不输出,
代码展示:
C语言——文件操作

用格式化的方式读写文本文件

1.对文件进行格式化输入输出,可以fprintf函数和fcanf函数,读写对象是文件,调用方式为:

fprintf(文件指针,格式字符串,输出表列);
fscanf(文件指针,格式字符串,输入表列);

注意点:
1.由于在输入时要将文件中的ASCII码转换为二进制形式在保存在内存变量中,在输出时又要将内存中的二进制转换成字符,要花费较多时间,因此,在内存与磁盘频繁交换数据的情况下,最好不用
代码展示:
C语言——文件操作
C语言——文件操作

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

1.C语言允许用read函数从文件中读一个数据块,用fwrite函数向文件写一个数据块,在读写时以二进制形式进行的,在向磁盘写数据时,直接将内存中一组数据原封不动,不加转换地复制到磁盘文件上,在读入时也是将磁盘文件中若干个字节的内容一批读入内存

2.它们的一般调用形式为

fread(buffer,size,count,fp);
fwrite(buffer,size,count,fp);

其中:

buffer:是一个地址。
对于fread来说,它是用来存放从文件读入的数据的存储区的地址
对于fwrite来说,是要把此地址开始的存储区中的数据向文件输出(以上指的是起始地址)
size:要读写的字节数
count:要读写多少个数据项(每个数据项长度为size)
fp:FILE类型指针

fread或者fwrite函数的类型为整型,如果fread和fwrite函数执行成功,则函数返回值为形参count值(一个整数),即输入或输出数据项的个数。
代码展示:
C语言——文件操作
C语言——文件操作

随机读写数据文件

1.文件位置标记
用来指示"接下来要读写的下一个字符的位置"

2.文件位置标记的定位
可以强制使文件位置标记指向文件开头
2.1用rewind函数使文件位置标记指向文件开头
rewind函数的作用是使文件位置标记重新返回文件的开头,同时feof函数的值会恢复为0(假),此函数没有返回值

2.2用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字节处

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

ftell函数的作用是得到流式文件中文件位置标记的当前位置
如果调用函数时出错(如不存在fp指向的文件),ftell函数返回值为-1L
i = ftell(fp);                    //变量i存放文件位置
if(i == -1L) printf("error\n");   //如果调用函数时出错,输出error

代码展示:
C语言——文件操作
C语言——文件操作

文件读写出错检测

1.ferror函数:在调用各种输入输出函数(如putc,getc,fread,fwrite)时,如果出现错误,
除了函数返回值有所反映以外,还可以用ferror函数检查,

调用形式:
ferror(fp);
1.1如果返回值为0,表示为出错,如果返回一个非零的值,表示出错
1.2对同一个文件每一次调用输入输出函数,都会残生一个新的ferror函数值,因此,应当在调用一个输入输出函数后
立即检查ferror函数的值,否则信息会丢失
1.3在执行fopen函数时,ferror函数的初始值自动设置为0

2.clearerr函数
作用:是使文件出错标志和文件结束标志置为0,假设在调用一个输入输出函数时出现错误,ferror函数值为一个非零值,应该立即调用clearerr(fp),使ferror(fp)的值变成0,以便再进行下一次检测

注意点:
1.只要出现文件读错标志,它就一直保留,直到对同一文件调用clearerr函数或rewind函数,或任何其他一个输入输出函数

谭浩强yyds!

GL
GL 一个酷爱健身,对其他事情三分热度de爱国的小青年

发表评论