在上一篇文章中,我讲述了有关ASCII文件的读写,那二进制文件的读写又该怎么进行编码呢?
二进制文件的读写
二进制文件保存的是数据在机器内部的映像,将数据在机器内部的映像原式原样的写入文件可以用fwrite函数;将文件中的二进制比特串原式原样写入某个变量可以用函数fread。
fwrite函数
fwrite函数用于写二进制文件,它可以将一个变量或一个数组在内存中的表示原式原样地写到文件中去。
fwrite函数的格式为:
fwrite(buffer,size,count,fp);
其中,buffer是需要写入的变量在内存中的起始地址;size是变量类型占据的字节数;count是写入变量的个数;fp是文件指针。
如果要将整型变量x写入文件,可用如下语句:
fwrite(&x,sizeof(int),1,fp);
如果要将一个10个元素的整型数组a中的所有元素写入文件,可用如下语句:
fwrite(a,sizeof(int),10,fp);
案例:设计一个程序,将整数1~10依次写入一个空的二进制文件file1。
#include<stdio.h>
int main(){
FILE *fp;
int i;
if((fp=fopen("D:\\file1","wb"))==NULL){
printf("Can't open the file!'");
return 1;
}
for(i=1;i<=10;i++){
fwrite(&i,sizeof(int),1,fp);
}
fclose(fp);
return 0;
}
如果直接用文本编辑器打开,则会显示一堆乱码。但通过观察文件的大小,我们发现,file1占据了4×10=40个字节。
fread函数
fread函数用于读二进制文件。它可以从文件中读入一个变量或一组同类的变量在内存中的表示。
fread函数的格式为:
fread(buffer,size,count,fp);
其中,buffer是读入数据中的存放地址;size是变量类型占据的字节数;count是写入变量的个数;fp是文件指针。
案例:从二进制文件file1读入10个整数。
#include<stdio.h>
int main(){
FILE *fp;
int i,a;
if((fp=fopen("D:\\file1","rb"))==NULL){
printf("Can't open the file!'");
return 1;
}
for(i=1;i<=10;i++){
fread(&a,sizeof(int),1,fp);
printf("%d ",a);
}
fclose(fp);
return 0;
}
文件的顺序访问
什么是文件的顺序访问
按文件中的内容顺序进行读写称为顺序访问。
写文件时,把数据按顺序写在一个空文件中或从文件尾开始写;读文件时,从文件的第一个数据开始往后依次读取一定数量的数据或读取文件的全部数据。
案例:读取file1文件中的第5个和第6个整数,并将它们显示在显示器上。
#include<stdio.h>
int main(){
FILE *fp;
int i,x;
if((fp=fopen("D:\\file1","rb"))==NULL){
printf("Can't open the file!'");
return 1;
}
for(i=0;i<4;i++){
fread(&x,sizeof(int),1,fp);
}
fread(&x,sizeof(int),1,fp);
printf("%d ",x);
fread(&x,sizeof(int),1,fp);
printf("%d ",x);
fclose(fp);
return 0;
}
该代码中,当需要读取第k个数时,需要先读前面k-1个整数。如果文件很大,包含了成千上万个整数,读取k个整数将会花费大量的时间,所以更好的解决方案是采用文件的随机访问。
feof函数
大多数情况下,读文件时往往并不知道文件中有多少信息。那么如何知道该调用教程fread()读文件的函数才能保证文件中的数据全部读完呢?
函数名称 | 判断(是否全部读完)的依据 |
fgetc()函数读取ASCII文件 | 读到文件尾时返回值是EOF |
fgets()函数读ASCII文件 | 读到文件尾时返回值是NULL |
fscanf()/fread()函数 | 读到文件尾时会返回NULL |
fscanf()/fread()函数(通用的判断方法) | 使用feof()函数 |
案例1:从ASCII文件file中读取所有整数。
#include<stdio.h>
int main(){
FILE *fp;
int k;
if((fp=fopen("D:\\file","r"))==NULL){
printf("Can't open the file!'");
return 1;
}
while(1){
fscanf(fp,"%d",&k);
if(feof(fp)) break;
printf("%d\t",k);
}
fclose(fp);
return 0;
}
案例2:从二进制文件file1中读取所有整数。
#include<stdio.h>
int main(){
FILE *fp;
int k;
if((fp=fopen("D:\\file1","rb"))==NULL){
printf("Can't open the file!'");
return 1;
}
while(1){
fread(&k,sizeof(int),1,fp);
if(feof(fp)) break;
printf("%d\t",k);
}
fclose(fp);
return 0;
}
运行结果如下:
文件的随机访问
随机读写文件中某个位置的数据称为文件的随机访问。
文件定位指针
每个文件指针指向的FILE类型的变量中都保存了一个下一次读写的位置,这个位置称为文件定位指针。既然文件读写的位置是由文件定位指针指定,只要能设置文件定位指针的值,就能实现文件的随机访问。
C语言提供了3个与文件定位指针操作有关的函数,分别是:
- rewind
- fseek
- ftell
rewind函数
rewind函数的作用是将文件定位指针重新返回到文件的开头,即第0个字节。这个函数没有返回值。
案例:从二进制文件file1中读取所有整数显示在显示器上以及写入ASCII文件file2。
#include<stdio.h>
int main(){
FILE *fp1,*fp2;
int k;
if((fp1=fopen("D:\\file1","rb"))==NULL){
printf("Can't open the file!'");
return 1;
}
while(1){
fread(&k,sizeof(int),1,fp1);
if(feof(fp1)) break;
printf("%d ",k);
}
rewind(fp1);
if((fp2=fopen("D:\\file2.txt","rb"))==NULL){
printf("Can't open the file!'");
return 1;
}
while(1){
fread(&k,sizeof(int),1,fp1);
if(feof(fp1)) break;
fprintf(fp2,"%d ",k);
}
fclose(fp1);
fclose(fp2);
return 0;
}
运行结果:
fseek函数
fseek函数用于设置文件定位指针的值,它的格式为:
fseek(fp,n,start);
其中,fp是文件指针;n是文件定位指针移动的字节数;start表示从何处开始移动。start的值如下表所示:
起始点 | 符号常量 | 对应的值 |
文件开始 | SEEK_SET | 0 |
文件定位指针当前位置 | SEEK_CUR | 1 |
文件末尾 | SEEK_END | 2 |
将文件定位指针移到文件头,可用如下语句:
fseek(fp,0,SEEK_SET);
将文件定位指针移到文件尾,可用如下语句:
fseek(fp,0,SEEK_END);
将文件定位指针移到当前位置后面第10个字节,可用如下语句:
fseek(fp,10,SEEK_CUR);
将文件定位指针移到当前位置前面第10个字节,可用如下语句:
fseek(fp,-10,SEEK_CUR);
案例:从二进制文件file1中读取第5、第6整数。
#include<stdio.h>
int main(){
FILE *fp;
int x;
if((fp=fopen("D:\\file1","rb"))==NULL){
printf("Can't open the file!'");
return 1;
}
fseek(fp,4 * sizeof(int),SEEK_CUR);
fread(&x,sizeof(int),1,fp);
printf("%d\n",x);
fread(&x,sizeof(int),1,fp);
printf("%d\n",x);
fclose(fp);
return 0;
}
ftell函数
ftell函数的作用是获取文件定位指针的值。格式为:
ftell(fp);
案例:读取二进制文件file1的所有数据及位置。
#include<stdio.h>
int main(){
FILE *fp;
int k,pos;
if((fp=fopen("D:\\file1","rb"))==NULL){
printf("Can't open the file!'");
return 1;
}
while(1){
pos = ftell(fp);
fread(&k,sizeof(int),1,fp);
if(feof(fp)) break;
printf("%d %d\n",pos,k);
}
fclose(fp);
return 0;
}
执行程序,运行结果如下:
整型数在文件中占了四个字节的空间。
2023年过去的11个月中,你过得怎样?对过往,别纠缠;对未来,别焦虑;对感情,别辜负。愿你的2023,不负所寄,不留遗憾。
标签:fp,文件,file1,重要,函数,int,C语言,printf From: https://blog.51cto.com/u_16174658/8664244