C语言文件处理

文件与流

将数据存储在变量或数组中,数据在程序运行结束后这些数据将会被释放,而文件则可以永久地保存数据。
C语言中,文件不过是一个按顺序组成地字节流,流就是字节的序列。
当一个文件被打开时,就会有一个流与这个文件联系在一起。当一个程序开始执行时,会有三个流被自动打开:

  • 标准输入(stdin)
  • 标准输出(stdout)
  • 标准错误 (stderr)

流提供了文件与程序之间进行信息交换的通道。

每次打开一个文件都会返回一个指向FILE结构体类型(在头文件stdio.h中定义)的指针,FILE结构体类型包含了用于文件处理的信息。
在多数操作系统中,这个结构体中包含一个文件描述头,即针对操作系统中打开文件列表的一个数组的整数索引,数组中的每个元素包含有一个文件控制块(FCB),而操作系统正是利用文件控制块(FCB)中的信息来管理一个特定的文件。
每个文件,要么以一个文件结束标记标记文件的结束,要么以记录在系统数据结构中的指定数目的字节数作为文件的结束,这个由程序所运行平台决定。

文件处理函数

以下面这个程序为例展开说明。
这个程序用于记录客户的账号 姓名 和 余额信息,将输入的客户信息保存到文件中。

#include<stdio.h>

int main(){
	FILE *cfPtr = fopen("clients.txt","w");
	
	if(cfPtr == NULL){
		puts("文件无法打开!");
	}
	else{
		puts("输入 账号 、 姓名 和 余额,按下 ctrl+z 回车 结束输入:");
		printf("? ");
		
		unsigned int account;
		char name[30];
		double balance;
		
		scanf("%d%29s%lf", &account, name, &balance);
		
		while(!feof(stdin)){
			fprintf(cfPtr,"%d %s %.2f\n", account, name, balance);
			printf("? ");
			scanf("%d%29s%lf", &account, name, &balance);
		}
	}
	fclose(cfPtr);
} 

FILE*文件指针

程序开始定义了一个FILE*类型的变量cfPtr,cfPtr是一个指向FILE结构体类型的指针。C程序总是用一个单独的FILE结构体来管理每个文件,每个打开的文件都有一个单独声明的、类型FILE的指针,该指针用来实现对文件的访问,通过FILE结构体来间接地访问操作系统中相应的文件的文件控制块(FCB)。

函数fgetc和fputc

函数fgetc需要一个文件指针作为实参,作用是向传入的文件指针指向的目标文件读入一个字符,如果传入的参数是stdin,fgetc(stdin)作用等同于函数getchar();
函数fputc需要一个字符型(char)和一个文件指针作为实参,作用是向传入的文件指针指向的目标文件写入传入的实参字符,例如,fputc(‘a’,stdout)的作用等同于putchar(‘a’)。

函数fopen

函数fopen的返回值是指向其所打开文件的FILE结构体类型的指针,若文件未成功打开,fopen返回NULL。
fopen有两个实参:

  • 文件名(可以包括表示文件存储位置的路径信息)
  • 文件的打开模式

FILE *cfPtr = fopen("clients.txt","w");
这条语句的含义是:以文件打开模式"w",建立起一个与名为client的文件进行通信的通道。
函数fopen的返回值是指向其所打开文件的FILE结构体类型的指针,被赋值给了文件指针变量cfPtr,若文件未成功打开,fopen返回NULL。

文件打开模式说明

模式说明
r为读操作打开一个已存在的文件
w为写操作创建一个文件,若文件存在,则丢弃其中的当前内容
a为在文件末尾进行写而打开或创建一个文件,即给文件添加数据的写操作
r+为更新(读/写)而打开一个已存在的文件
w+为更新而创建一个文件,若文件已存在,则丢弃其中的内容
a+为读和更新打开或创建一个文件,所有的写都在文件末尾进行
rb以二进制读模式,为读操作打开一个已存在的文件
wb以二进制模式,为写操作打开一个已存在的文件,若文件存在,丢弃其中内容
ab添加:以二进制模式,为在文件末尾进行的写操作打开或者创建一个文件
rb+以二进制模式,为更新(读/写)二打开一个已存在的文件
wb+以二进制模式,为更新而创建一个文件,若文件存在,丢弃其中内容
ab+添加:以二进制模式,为更新而打开或者创建一个文件;写操作在文件末尾进行

此外,C11还通过在模式w、w+、wb或wb+后面增加一个x,提供互斥写模式。在互斥写模式下,如果文件已经存在或者不能被创建,则函数fopen的执行将失败。
若能按照互斥写模式成功打开一个文件,且底层系统支持互斥文件访问,则在该文件被打开的时间段内,只有你的程序能够访问它。

函数feof

函数feof的实参是一个指向欲测试是否带有文件结束标记的文件指针,若文件结束标记已经被设置,则函数返回一个非零值,否则返回0。
while(!feof(stdin)) 这条语句中,函数feof检查是否为标准输入stdin检测到文件结束标记。文件结束标记用于通知程序不再有数据需要处理了。
本条语句中,当用户键入代表文件结束的组合键时,文件结束标记将被写入stdin中。
本条语句中,在stdin中文件结束标记未被设置前,while循环会一直执行。

函数fprintf

函数fprintf的作用是向文件写入数据。
函数fprintf基本上是等价于函数printf的,只不过fprintf函数需要多接收一个文件指针实参,作为数据写入的目标文件。
如果将stdout作为文件指针,则fprintf函数将数据输出到标准输出中。
示例:fprintf(stdout," %d %s %.2f\n",66,"hello",66.66);

函数fscanf

函数fcanf的作用也基本是等价于函数scanf的,函数fcanf需要多接收一个人家指针作为实参,这个文件指针指向的文件就是要读取数据的目标文件。fscanf(cfPtr,"%d%29s%lf",&accont,name,&balance);
上面这条语句,程序会将cfPtr所指向的目标文件读出数据,按顺序把数据放入对应的地址。
函数fscanf的返回值是成功读取的数据项个数,若读取数据过程发生了问题,则返回EOF。

函数fwrite和fread

函数fwrite的功能是:将从某个特定地址开始存储的特定数目的字节数据,从内存中转移到一个文件,其中参数“文件位置指针”指示的是文件中这些字节数据被写入的起始地址。
函数fread的功能是:将文件位置指针指示的特定位置开始的特定数目的字节数据,从一个文件中转移到某个特定地址开始的一个内存区域中。
例如:
fwrite(&number, sizeof(int), 1, fPtr);
上面这条语句的意思是从number的首地址开始,向文件指针fPtr指向的目标文件写入1个大小为sizeof(int)个字节的数据项。返回值为成功输出的数据项的个数。
fread(&number, sizeof(int), 1, fPtr);
fread和fwrite相反,该语句是:从fPtr指向的目标文件的文件指针位置开始读出1个大小为sizeof(int)个字节的数据项,从number首地址开始存。返回值为所读数据项的个数。若返回值小于第三个实参,说明出现了读错误。

函数rewind

该函数用于文件位置指针(文件偏移量)的复位。
为了从顺序文件中提取特定的数据,程序通常是从文件头开始连续的读取数据,直到发现欲提取的数据为止。程序在执行过程中,可能需要对顺序存取文件中特定的数据进行多次处理(每一次都从头开始)。这时可以调用下面这个函数:
rewind(cfPtr);
将程序的文件位置指针,指示文件中下一个将被读/写的字节编号,重新定位在cfPtr所指向文件的开头(即字节编号为0)。
文件位置指针实际上并不是一个指针,而是一个整数值,这个整数值表示文件中下一个读/写操作将发生在哪个字节位置上,也称为文件偏移量
文件偏移量时与文件相联系的FILE结构体类型的一个成员。

函数fseek

函数fseek的原型为:
int fseek(FILE *stream, long int offset, int whence);
其中,offset是stream所指向文件的,从whence位置开始,文件位置指针(文件偏移量)将要搜索扫过的字节数——正的offset表示向前扫,负表示向后扫。
表示文件位置的搜索起始位置的实参whence有三个可选值:
SEEK_SET ,SEEK_CUP,SEEK_END
SEEK_SET表示搜索的起始位置为文件的开头位置,SEEK_CUR表示搜索的起始位置为文件的当前位置,SEEK_END表示偏移量从文件尾部开始计算。
函数fseek返回一个非0值,即定位到文件开始位置之前。

函数fclose

当用户键入文件结束标记后,程序将用函数fclose关闭文件。
函数fclose的参数是一个文件指针,而不是文件名。
若程序中没有显示地调用fclose,那么程序会在结束退出时,关闭所有未关闭地文件。主要是程序结束退出时,而不是函数结束退出。

关闭一个文件能够释放掉其所占用的资源。其他用户或程序也许在等待使用这些资源。一旦明确程序不在访问一个文件后,应立即关闭这个文件,而不是等程序结束退出操作系统来关闭。
示例:fclose(cfPtr);

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_200_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值