对文件任意位置的访问,称为随机访问,通过随机访问的文件,简称为随机文件。
要使用一个随机文件,即使用一个文件当中任意位置的内容,必须要指明是需要什么位置的内容,这样就涉及到一个文件内部定位的问题。C 中虚拟了一个指针,通过这个指针,指向文件正在访问的内容。所以文件内部指针就是正在访问的内容的位置。
例如已经介绍过的顺序文件,也有一个内部位置的问题,只是相对简单。每次打开一个顺序文件,指针总是按打开方式的不同指向不同的位置,文件头或者文件尾,然后每次读取或写入操作完成之后,指针总是向后移动一个数据单位(由操作函数给出),然后下一次操作即可在指针位置进行了。
C语言中给出了指针定位的函数:
1、fseek()定位函数
fseek()函数的声明形式为:
int fseek(FILE *fp,long bytes,int origin);
参数说明:
fp 是文件指针。
origin 是起始点的类型,包括三种:文件头、当前位置、文件尾,参数值分别为 0、1、2。
若origin为0,bytes 表示从文件头开始距离为bytes个字节处;若origin为1,且bytes为正数,表示从当前指针位置向后隔bytes个字节处,bytes为负数,表示从当前指针位置向前隔bytes个字节处;若origin为2,表示从文件尾开始计算,bytes 只能为负值,表示从文件尾开向前隔bytes个字节数的位置。
函数的返回值是整数类型,如果定位成功,返回值为0,如果不成功,返回值是一个非0值。
例1:结构体数据,利用fseek 函数,修改第二个学生的信息
// 结构体数据,利用fseek 函数,修改第二个学生的信息
#include<stdio.h>
typedef struct
{
long stuNo;
char Name[30];
}student;
void main()
{
FILE * fp; //定义文件指针
// 写入
student stu[2]={152202010,"xiaoxi",152202014,"xiaojun"};
fp=fopen("D://test//file_operate//fwrite2.txt","wb+"); //以写的方式打开文件
if(fp==NULL)
{ // 如果打开不成功,输出错误信息后退出程序
printf("File open Error!");
return; //
}
else
{
printf("Please input the chars\n");
for(int i=0;i<2;i++)
{
fwrite(&stu[i],sizeof(student),1,fp);
}
// 读取
student stu1;
int n=1;
fseek(fp,0,0);
printf("The Files are as follow:\n");
n = fread(&stu1,sizeof(student),1,fp);
while(n)
{
printf("Her name is %s\n",stu1.Name);
printf("Her number is %ld\n",stu1.stuNo);
n = fread(&stu1,sizeof(student),1,fp);
}
student stu2={152202016,"xiabao"};
fseek(fp,sizeof(student),0);
fwrite(&stu2,sizeof(student),1,fp);
// 修改第二个学生信息后重新打印
fseek(fp,0,0);
n = fread(&stu1,sizeof(student),1,fp);
while(n)
{
printf("Her name is %s\n",stu1.Name);
printf("Her number is %ld\n",stu1.stuNo);
n = fread(&stu1,sizeof(student),1,fp);
}
printf("\n");
fclose(fp);
}
}
2、ftell()指针位置函数
ftell()函数的主要作用是返回位置指针所指向的操作位置。它的声明形式为:
long ftell(FILE *fp);
返回值是文件内位置指针所指向的位置,如果发生错误的话,比如文件指针指向的文件不存在等,返回值为-1。
例2:输出前两个学生的信息,利用ftell 函数,给出文件内部位置指针所在的操作位置
// 输出前两个学生的信息,利用ftell 函数,给出文件内部位置指针所在的操作位置
#include<stdio.h>
typedef struct
{
long stuNo;
char Name[30];
}student;
void main()
{
FILE * fp; //定义文件指针
// 写入
student stu[3]={152202010,"xiaoxi",152202014,"xiaojun",152202016,"xiaobao"};
fp=fopen("D://test//file_operate//stuData.txt","wb+"); //以写的方式打开文件
if(fp==NULL)
{ // 如果打开不成功,输出错误信息后退出程序
printf("File open Error!");
return; //
}
else
{
for(int i=0;i<3;i++)
{
fwrite(&stu[i],sizeof(student),1,fp);
}
// 读取
student stu1;
int n=1;
long position;
position = ftell(fp);
printf("position is %ld\n",position);
fseek(fp,0,0);
position = ftell(fp);
printf("position is %ld\n",position);
printf("The Files are as follow:\n");
n = fread(&stu1,sizeof(student),1,fp);
while(n)
{
position = ftell(fp);
printf("position is %ld\n",position);
printf("Her name is %s\n",stu1.Name);
printf("Her number is %ld\n",stu1.stuNo);
n = fread(&stu1,sizeof(student),1,fp);
}
printf("\n");
fclose(fp);
}
}
3、rewind()指针复位函数
rewind()函数的主要作用是将文件内部的位置指针重新设置在文件开头的位置。它的声明形式为:
void rewind(FILE *fp);
rewind(fp) 和 fseek(fp,0,0)实现的功能一样