【C语言】文件操作详解3(文件的随机读写和其他补充)
前言:
书接上回,由于文章过长,所以分了三篇文
若内容对大家有所帮助,可以收藏慢慢看,感谢大家支持
谢谢大家 ! ! !
上期给大家介绍了文件的顺序读写操作
这期我们就来聊聊文件的随机读写操作
一、文件的随机读写操作
文件的随机读写,顾名思义
在读写时可以定位到想要读写的地方
其中有几个函数,我来一一讲解
1.fseek函数(定位文件光标)
根据文件指针的位置和偏移量来自行定位文件内容的光标
语法:
int fseek ( FILE * stream, long int offset, int origin );
stream表示流(文件的文件指针)
offset表示当前位置相比于起始位置origin的偏移量
origin表示起始位置
(1)origin
表示起始位置
origin有且仅有三种选项:
SEEK_SER: 文件的起始位置SEEK_CUR: 文件指针的当前位置SEEK_END: 文件的末尾
(2)offset
表示当前位置相比于起始位置origin的偏移量
且注意,offset可为负数
正数就向右偏移,负数就向左偏移
如图解:

代码演示:
先将一串字符写入文件中,再用fseek来自行定位文件内容光标
最后打印出光标后的字符
(写入1234567890):

运行代码,将内容光标定位到文件的起始位置向右偏移4个字符:
c
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
FILE* pf = fopen("test.txt", "r");
//打开文件
if (pf == NULL)
{
perror("fopen");
//打印出错误信息
return 0;
//返回状态码 1 表示异常退出
}
fseek(pf, 4, SEEK_SET);
//将内容光标定位到文件的起始位置向右偏移4个字符
char ch;
while ((ch=fgetc(pf)) != EOF)
{
printf("%c", ch);
}
printf("\n\n");
fclose(pf);//关闭文件
pf = NULL;//置为NULL空指针
return 0;
}
运行结果:

通过运行结果,我们可以看到,我们只打印了起始位置后4位的字符,前4个字符跳过了
这就是因为fseek可以自行定位文件内容的光标
这里我定位到了距离文件起始位置偏移量为+4的位置,也就是从5开始打印
2.ftell(找到文件光标)
返回文件的内容光标相较于文件起始位置的偏移量
可以知道文件内容的光标现在在哪里
语法:
long int ftell ( FILE * stream );
stream表示流(文件的文件指针)
代码演示:
现在,先将文件的光标借助fseek函数定位到距离文件起始位置偏移量为+4的位置处,再用ftell函数得出文件的内容光标相较于文件起始位置的偏移量
代码如下:
c
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
FILE* pf = fopen("test.txt", "r");
//打开文件
if (pf == NULL)
{
perror("fopen");
//打印出错误信息
return 0;
//返回状态码 1 表示异常退出
}
fseek(pf, 4, SEEK_SET);
//将内容光标定位到文件的起始位置向右偏移4个字符储处
int ret=ftell(pf);
//得出文件的光标相较于文件起始位置的偏移量
printf("%d", ret);
//打印出偏移量
printf("\n\n");
fclose(pf);//关闭文件
pf = NULL;//置为NULL空指针
return 0;
}
运行结果:

果然,偏移量是4
所以,ftell函数可以知道文件内容的光标现在在哪里,并返回文件的内容光标相较于文件起始位置的偏移量从而更好读写
3.rewind(使光标返回起始位置)
让文件的光标返回起始位置
语法:
void rewind ( FILE * stream );
stream表示流(文件的文件指针)
代码演示:
现在,先用fputs先输出一些数据,再用rewind让光标返回起始位置,接着用fputs再次输出一些数据,最后观察文件内容
代码:
c
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
FILE* pf = fopen("test.txt", "w");
//打开文件
if (pf == NULL)
{
perror("fopen");
//打印出错误信息
return 0;
//返回状态码 1 表示异常退出
}
fputs("12345678", pf);
//先输出一些数据
rewind(pf);
//让光标返回起始位置
fputs("xxxx", pf);
//再次输出数据
printf("\n\n");
fclose(pf);//关闭文件
pf = NULL;//置为NULL空指针
return 0;
}
运行结果:

显然,在rewind的作用下,文件的内容光标先返回到了文件的起始位置,然后再输出"xxxx"数据
所以,rewind可以让文件的光标返回起始位置,便于输出
二、文件读写结束时的判定
文本的读写在这一期以及上一期给大家讲完了
那么,该如何判定文件读取是否结束呢?
这里我分为两种情况:
1.判定文本文件是否读取结束
判断返回值是否为EOF(fgetc) 或者NULL(fgets)
当
fgetc函数文件读取结束时,会返回EOF
当fgets函数文件读取结束时,会返回NULL
2.判定二进制文件是否读取结束
判断返回值是否小于实际要读取个数
由于
fwrite和fread函数的返回值是实际输入或输出的总元素个数(上节讲过不知道的可以去看看)
所以,可以通过比较返回值和实际要读取个数的大小
若 返回值 == 实际要读取个数 则读取结束
否则未读取结束
3.例题分析(拷贝文件)
光讲肯定是不行的,要有代码的实践才行,这里给大家讲解一道例题吧
问:如何将date.txt文件中的内容拷贝到copy_date.test文件中去
先在date.txt文件中写入一些字符

然后运行代码
注意:
因为date.test我们要输入数据,故用" r "只读的方式
因为copy_date.test我们要输出数据,故用" w "只写的方式
c
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void copy(FILE* p1, FILE* p2)//定义一个拷贝函数
{
char ch;
int sum = 0;
while ((ch = fgetc(p1)) != EOF)//当文件读取结束时停止
{
fputc(ch, p2);//一个字符一个字符拷贝
}
}
int main()
{
FILE* p1 = NULL;//初始化文件指针变量
FILE* p2 = NULL;//初始化文件指针变量
if ((p1 = fopen("date.txt", "r")) == NULL)//打开被拷贝的文件
{
printf("文件打开失败,未找到该文件\n\n");
return 0;
}
p2 = fopen("copy_date.test", "w");//打开要拷贝的文件
copy(p1, p2);//调用拷贝函数
fclose(p1);//最后关闭文件
p1 = NULL;//置空指针
fclose(p2);
p2 = NULL;
return 0;
}
运行结果:
观察copy_date.test文件内容是否完成拷贝

结果显而易见,完成了拷贝
结语
本期资料来自于:

OK,所有的文件操作详解到这里就结束了
由于文章过长,所以分了三篇文
若内容对大家有所帮助,可以收藏慢慢看,感谢大家支持
本文有若有不足之处,希望各位兄弟们能给出宝贵的意见。谢谢大家!!!
新人,本期制作不易希望各位兄弟们能动动小手,三连走一走!!!
支持一下(三连必回QwQ)