文件的操作
一、文件的概念
“文件”指存储在外部介质上数据的集合,这个数据集合有一个名称,叫做文件名
计算机存储分为2块:1. 内存(内部存储) 2. 硬盘(外部存储、外部介质)
二、文件的分类
1. 从用户的角度看,文件可以分为普通文件和设备文件
2. 从文件编码方式来看,文件可以分为ASCII码文件和二进制码文件两种,ASCII码文件也称为文本文件,二进制码文件是按二进制的编码方式来存放文件的
三、文件操作的步骤及原理
(1)文件的操作步骤
1. 引入头文件 stdio.h
2. 定义文件指针
3. 打开文件
4. 文件读写
5. 关闭文件
(2)对文件的读和写是最常用的文件操作,在C语言中提供了多种文件读写的函数
字符读写函数:fgetc( )函数和fputc( )函数
字符串读写函数:fgets( )函数和fputs( )函数
数据块读写函数:fread( )函数和fwrite( )函数
格式化读写函数:fscanf( )函数和fprintf( )函数
(3)文件操作原理
1. 文件缓冲流
2. 文件输出流
C语言文件指针
一、C语言文件指针
在C语言中用一个指针变量指向一个文件,这个指针称为文件指针
定义说明文件指针的一般形式为:
FILE *指针变量标示符;
其中FILE应为大写,它实际上是由系统定义的一个结构体,该结构体中含有文件名、文件状态和文件当前位置等信息
例:FILE *fp;
二、文件的打开和关闭
(1)文件的打开函数(fopen( )函数)
1. fopen( )函数用来打开一个文件,其调用的一般形式为:
文件指针变量名 = fopen(文件名,使用文件方式);
其中:
“文件指针变量名”必须是FILE类型的指针变量
“文件名”是被打开文件的文件名
“使用文件方式”是指文件的类型和操作要求
“文件名”是字符串常量或字符串数组
2. 打开文件的代码实现:
// 定义文件指针
FILE *fp = NULL;
// 打开文件
// 如果打开文件成功,返回文件的首地址;如果打开文件失败,返回NULL
fp = fopen("a.txt", "r"); // r表示只读
// 其意义是在当前目录下打开文件a.txt,只允许进行“读”操作,并使用fp指向该文件
(2)文件的关闭函数(fclose( )函数)
1. 文件一旦使用完毕,应当使用关闭文件函数把当前文件关闭,以避免文件的数据丢失等错误
2. fclose( )函数调用的一般形式是:
fclose( 文件指针);
例:
// 关闭文件
fclose(fp);
3. 正常完成关闭文件函数操作时,fclose( )函数返回值为0,如返回非零值,则表示有错误发生
4. 注意: 如果文件写操作时,没有进行文件关闭,可能会导致文件写入失败
(3)打开文件和关闭文件操作的代码实现
注意:打开失败是因为我的路径下没有a.txt文件
三、文件的使用和注意事项
(1)文件使用方式(使用文件的方式共有12种)
1. r:打开一个已经存在的文件,准备从文件中读取数据,不能向文件中写数据
2. w:创建一个新文件,准备向文件中写入数据,不能从文件中读取数据,如果文件已经存在,这个文件将被覆盖(先删后建)
3. a:打开一个已经存在的文件,准备在文件尾部追加数据,不能从文件中读取数据,如果文件不存在,则创建这个文件准备写入数据
4. r+:打开一个已经存在的文件,准备读写,既可以读数据,也可以写入数据
5. w+:创建一个新文件,准备读写,如果文件已经存在,则覆盖原文件
6. a+:等价于a,但可以从文件中读取数据
7. t:打开一个文本文件
8. b:打开一个二进制文件
(2)文件使用方式注意事项
文件使用方式由r、w、a、t、b和+六个字符拼成,各个字符的含义是:
1. r(read):读
2. w(write):写
3. a(append):追加
4. t(text):文本文件
5. b(binary):二进制文件
6. +:读和写
字符读写函数fgetc( )和fputc( )
一、字符写入文件函数fputc( )
字符读写函数是以字节为单位的读写函数,每次从文件中读出或向文件中写入一个字符
fputc( )函数的功能是把一个字符写入指定文件中,函数的调用形式为:
fputc(字符量,文件指针);
例如:fputc('c', fp);
其意义是把字符c写入fp所指向的文件中
二、读文件中字符函数fgetc( )
fgetc( )函数的功能是从指定文件中读取一个字符,函数的调用形式为:
字符变量 = fgetc(文件指针);
例如:char ch = fgetc(fp);
其意义是从打开的文件fp中读取一个字符并送入ch中
(1) 对于fgetc( )函数的使用注意:
1. 读取字符的结果也可以不向字符变量赋值,例:fgetc(fp);但是读出的字符不能保存
2. 在文件内部有一个位置指针,用来指向文件的当前读写字节,在文件打开时,该指针总是指向文件的第一个字节,使用fgetc( )函数后,该位置指针将向后移动一个字节
三、字符读写的代码实现
(1)将字符串中的字符逐个写入文件代码实现
// 定义要写入文件的字符串
char str[] = "I believe I can fly";
// 定义文件指针并且以w+的方式打开文件
FILE *fp = fopen("fputc.txt", "w+");
// 判断文件是否打开成功
if (fp != NULL)
{
// 将字符串中的字符逐个写入fp指向的文件中去
for (int i=0; i<sizeof(str)/sizeof(char); i++)
{
fputc(str[i], fp);
}
}
// 关闭文件
fclose(fp);
(2)将文件中的字符串逐个字符读出代码实现
注意事项:
1. EOF是文件末尾的标志
2. ch == EOF 可以理解为已经读取到文件最后了
四、应用
设计要求:键盘上输入一行字符,写入一个文件,再把该文件内容连续显示在屏幕上
设计注意:
1. rewind(fp)的作用是把文件指针,重新指向文件的首地址
字符串的读写函数fgets( )和fputs( )
一、字符串写入文件函数fputs( )
字符串写入文件函数fputs( )的格式:
fputs(字符串,文件指针);
其中:字符串可以使字符串常量,也可以是字符数组名或指针变量
(1)字符串写入文件函数的代码实现
使用注意:
1. fputs( )函数有返回值,返回值为int类型,返回的是写入字符串的长度
(2)字符串追加到文件当中的代码实现
二、读取文件中字符串的函数fgets( )
从文件中读取字符串的函数fgets( )的格式:
fgets(字符数组名,n,文件指针);
其中的n是一个正整数,表示从文件中读出的字符串不超过n-1个字符,在读取的最后一个字符加上字符串的结束标志’\0’
例如:fgets(str, n, fp);
其意义是从fp所指向的文件中,读出n-1个字符送入字符数组str中
(1)从文件中读取字符串的代码实现
使用注意:
1. fgets( )函数读取的时候,当文件内容读取完毕后,会给字符串加上结束符’\0’
2. fgets( )函数读取的时候,当遇到’\n’或者EOF,读取结束(在读出n-1)字符前
三、写入中文的问题(一个汉字占3个字节(字符))
结果分析:
运行显示乱码,不能正确的显示”张三丰”,原因是因为一个字符占3个字节,而str2只有3个字节,所以只能存储3-1个字符(张的第一个字节,第二个字节和’\0’),如果数组str2长度为4的话,则可以显示张
数据块读写函数fread( )和write( )
C语言还提供了用于整块数据的读写函数,可以用来读写一组数据,如一个数组,一个结构体变量的值等
读数据块函数fread( )调用的一般形式为:
fread(buffer,size,count,fp);
写数据块函数fwrite( )调用的一般形式为:
fwrite(buffer,size,count,fp);
其中:
buffer:是一个指针,在fread( )函数中,它表示存放输入数据的首地址,在fwrite( )函数中,它表示存放数据的首地址
size:表示数据块的字节数
count:表示要读写的数据块块数
fp:表示文件指针
一、fwrite( )函数操作的代码实现
二、fread( )函数操作的代码实现
三、用fwrite( )函数写入二进制数的代码实现
注意:查看文本文件的方式:
四、应用
设计要求:将一个结构体数组的内容,写入一个文件中,再读出这两个学生的数据显示在屏幕上
设计注意:
1. 计算结构体数组中的元素个数的方法
// 这种方式也可以计算出结构数组中的元素个数
int n = sizeof(stu)/sizeof(Student);
printf("%d", n);
格式化读写函数fscanf( )和fprintf( )
fscanf( )函数和fprintf( )函数与我们经常使用的scanf( )函数和printf( )函数功能相似,都是格式化读写函数,两者的区别在于fscanf( )函数和fprintf( )函数的读写对象不是键盘和显示器,而是磁盘文件
fscanf( )函数和fprintf( )函数这两个格式化读写函数的调用格式为:
fsacnf(文件指针,格式字符串,输入表列);
fprintf(文件指针,格式字符串,输出表列);
一、fprintf( )函数操作的代码实现
设计要求:要将数据按照这样的格式读进去 0#1;
二、fscanf( )函数操作的代码实现
三、应用
设计要求:使用fprintf( )函数和fscanf( )函数将一个二维数组逐行写入到文件中,并且读取出来
1,2#
3,4#
5,6#
文件随机读写的实现
文件随机读写的关键是按要求移动位置指针,这称为文件的定位
一、文件的定位
移动文件内部位置指针的函数主要有两个,即rewind( )和fseek( ),rewind( )函数之前已经用过,其调用形式为:
rewind(文件指针);
它的功能是把文件内部的位置指针移动到文件首部
fseek( )函数的调用形式为:
fseek(文件指针,位移量,起始点);
其中:
“文件指针”指向被移动的文件
“位移量”表示移动的字节数,要求位移量是long类型数据,以便在文件长度大于64KB时不会报错,当用常量表示位移量时,要求常量加后缀“L”
“起始点”表示从何出开始计算位移量,规定的起始点有三种:文件首、当前位置和文件尾
起始点 标示符号 数字表示
文件首 SEEK_SET 0
当前位置 SEEK_CUR 1
文件尾 SEEK_END 2
例:fseek(fp, 100L, 0);
其意义是把fp指向文件中的位置指针,移动到离文件首100个字节处
注意:fseek( )函数一般用于二进制文件中,在文本文件中由于要进行转换,故往往计算的位置会出现错误
二、文件的随机读写
设计要求:读取student.data中第二个学生的信息
文件检测函数feof( )介绍
一、文件结束检测函数feof( )
文件检测函数feof( )的调用格式:
feof(文件指针);
功能:判断文件是否处于文件结束的位置,如果文件结束,则返回值为1,否则返回值为0
二、文件结束函数操作的代码实现
使用注意:
当使用feof( )函数作为判断条件时,总会多执行一次