C语言 文件操作(二)

上一篇主要讲了文件文本形式的读写函数以及文件的关闭与打开,详情参考C语言 文件操作(一)。接下来主要介绍文件的二进制形式的读写以及文件指针定位等。

二进制形式的读写

  二进制文件不是以ASCII代码存放数据的,它将内存中数据存储形式不加转换地传送到磁盘文件,因此它又称为内存数据的映像文件。因为文件中的信息不是字符数据,而是字节中的二进制形式的信息,因此它又称为字节文件。

  对二进制文件的操作也需要先打开文件,用完后要关闭文件。二进制文件除了可以作为输入文件或输出文件外,还可以是既能输入又能输出的文件。这是和ASCII文件不同的地方。

fwrite()函数

调用格式:size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);

功能:把数据的二进制写入到文件中。

参数说明:
  ptr:要写入的数据的首地址
  size:写入的字节数
  nmemb:写入的次数
  stream:文件指针,fopen的返回值

返回值:成功写入的次数

fread()函数

调用格式:size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

功能:从文件中以二进制的形式读取数据到内存中

参数说明:
  ptr:读取数据后的存储位置
  size:每次读取的字节数
  nmemb:读取的次数
  stream:文件指针,fopen的返回值

返回值:实际读取数据块的个数

从stu.dat文件中读取数据到学生结构变量中,并显示结构变量中的内容。

#include <stdio.h>

typedef struct Student
{
	char name[20];
	int id;
	short age;
}Student;

int main()
{
	FILE* fwp = fopen("stu.dat","wb+");
	Student stu = {"xixi",10086,28};
	int ret = fwrite(&stu,1,sizeof(Student),fwp);

	// 把文件位置指针调整到开头
	rewind(fwp);
	Student stu1 = {};
	fread(&stu1,1,sizeof(Student),fwp);
	printf("%s %d %hd\n",stu1.name,stu1.id,stu1.age);
}

运行结果:

$ ./a.out

xixi 10086 28

文件流之文件的定位

  文件的随机读写有时用户想直接读取文件中间某处的信息, 若用文件的顺序读写必须从文件头开始直到要求的文件位置再读, 这显然不方便。C语言标准库提供了一组文件的随机读写函数, 即可以将文件位置指针定位在所要求读写的地方直接读写。

使用"w"、"r"打开的文件位置指针都在文件的开头,而使用"a"打开的文件,位置指针都在末尾。
位置指针会随着数据的读写而变化。

fseek()函数

调用格式:int fseek(FILE *stream, long offset, int whence);

功能:设置文件的位置指针,位置指针会设置到 基础位置+偏移值

参数说明:
  stream:文件指针
  offset:偏移值
  whence:基础位置

常量描述
SEEK_SET文件的开头,offset必须是一个非负值
SEEK_CUR文件指针的当前位置,offset可正可负
SEEK_END文件末尾,offset可正可负,如果是正直将定位到文件尾的后面
返回值:如果成功,则该函数返回零,否则返回非零值。
ftell()函数

调用格式:long ftell(FILE *stream);

功能:获取文件的位置指针,位置指针当前所在的字节数

rewind()函数

调用格式:void rewind(FILE *stream);

功能:把文件的位置指针,调整到开头。

实现一个函数,计算文件的大小。

#include <stdio.h>

size_t file_size(const char* path)
{
	FILE* frp = fopen(path,"r");
	if(NULL == frp)
	{
		perror("fopen");
		return 0;
	}

	// 调整文件位置指针到末尾
	fseek(frp,0,SEEK_END);

	return ftell(frp);
}

int main()
{
	printf("%d\n",file_size("day03.zip"));
}

注意:
当数据写入后并没有立即同步到磁盘中,而存储在缓冲区中,只有满足以下条件时才会从缓冲区中写入到磁盘中。
1、从输出调整到输入。
2、缓冲区满4k
3、文件关闭
4、程序结束
5、手动刷新 fflush()函数;
  调用格式:int fflush(FILE *stream);
  功能:该函数将输出缓冲区的内容实际写入文件中, 而将输入缓冲区的内容清除掉

其他函数

feof()函数

调用格式:int feof(FILE *fp)

功能:该函数用来判断文件是否结束

返回值
   0:假值,表示文件未结束。
   1:真值,表示文件结束。

  这个函数对二进制文件操作特别有用, 因为二进制文件中,文件结尾标志 EOF 也是一个合法的二进制数,只简单的检查读入字符的值来判断文件是否结束是不行的。如果那样的话, 可能会造成文件未结尾而被认为结尾, 所以就必须有 feof()函数。

下面的这条语句是常用的判断文件是否结束的方法。

while(!feof(fp)) 
	fgetc(fp);

ferror()函数

调用格式:int ferror(FILE *fp);

功能:检查由fp指定的文件在读写时是否出错

返回值:
   0:假值,表示无错误。
   1:真值,表示出错。

#include <stdio.h>

int main()
{
	FILE* frp = fopen("test.txt","r");
	if(NULL == frp)
	{
		perror("fopen");
		return -1;
	}

	int num = 0;
	float f = 0;
	char ch = 0;
	int ret = fscanf(frp,"%d %f %hhd",&num,&f,&ch);
	printf("%d %f %c %d\n",num,f,ch,ret);

}

clearerr()函数

调用格式:void clearerr(FILE *fp);

功能:清除由fp指定文件的错误标志。

exit()函数

调用格式:void exit(int status)

功能:exit()函数使程序立即终止执行,同时将缓冲区中剩余的数据输出并关闭所有已经打开的文件。

status:为0值表示程序正常终止,为非0值表示一个定义错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值