文件操作
- 1.文件相关概念
- 2.流和标准流
- 2.1流
- 2.2标准流
- 3.文件指针
- 4.文件的打开关闭
- 5.文件的顺序读写
- 6.文件的随机读写
- 6.1 fseek
- 6.2 ftell
- 6.3 rewind
- 7.⽂件读取结束的判定
- 7.1 feof
- 8.文件缓冲区
1.文件相关概念
2.流和标准流
2.1流
我们程序的数据需要输出到各种外部设备,也需要从外部设备获取数据,不同的外部设备的输⼊输出操作各不相同,为了⽅便程序员对各种设备进⾏⽅便的操作,我们抽象出了流的概念,我们可以把流想象成流淌着字符的河。
C程序针对⽂件、画⾯、键盘等的数据输⼊输出操作都是通过流操作的。
⼀般情况下,我们要想向流⾥写数据,或者从流中读取数据,都是要打开流,然后操作。
2.2标准流
3.文件指针
也就是说我们将文件的相关信息保存在名为FILE的结构体变量中,然后我们通过File*的指针来访问该结构体的
4.文件的打开关闭
⽂件在读写之前应该先打开⽂件,在使⽤结束之后应该关闭⽂件。
在编写程序的时候,在打开⽂件的同时,都会返回⼀个FILE*的指针变量指向该⽂件,也相当于建⽴了指针和⽂件的关系。
ANSI C规定使⽤ fopen 函数来打开⽂件,fclose 来关闭⽂件。
注意使用fopen函数时还应指定用什么方式来打开文件,接下来会介绍有关方式
区分一下“r”和“w”,r意为读取,w意为写。并且以读的方式打开就只能读,以写的方式打开就只能写
例子
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
FILE* pf = fopen("data.txt", "w");
if (pf == NULL)
{
perror("data.txt");//perror可以查明错误原因。
return 1;
}
fclose(pf);
pf=NULL://注意置为空指针
return 0;
}
当然以读的形式打开如果找不到当前文件的话则会新建一个data.txt文件,若存在data.txt文件则会将内容清空。其它的大家可以自己尝试
5.文件的顺序读写
scanf/fscanf/sscanf
printf/fprintf/sprintf
包括这些函数一起讲了
参数为文件指针
从文件中读取字符返回整形(也就是字符的ASCII码值),有些同学可能疑惑为什么返回的是整形实际上读取过程中可能遇到错误此时返回的就是EOF(end of file)就是-1,这样一想是不是用整形来接受就比较好理解了
参数为字符指针,整形,文件指针
从文件中读取num-1个字符(注意这里仅仅会读取文件中num-1个字符存放在字符串并主动将字符串第n个字符置为’\0’),并且倘若在读文件时遇到换行符默认为文件结尾将换行符保存在字符串中并将下一位字符置为’\0’,若读取过程没遇到错误返回的指针即为字符串指针否则返回NULL;
参数为整形(指的是字符ASCII码值或直接字符也行)和文件类型指针
将字符存入文件中。
参数文件类型指针和字符指针
将字符串存入文件中
参数为一个const修饰的字符指针和…
参数为文件类型指针和一个const修饰的字符指针,和…
参数为字符类型指针和一个const修饰的字符指针,和…
也许有些同学会觉得这怎么区分,其实我们可以从scanf来理解,我们往往使用scanf(‘%d’,&a)是这样的形式,那同理fscanf,sscanf后面两个参数也是如scanf的形式不同的只是第一个参数罢了
当然你肯定要掌握scanf函数才能真正区分这三个函数,如果不太理解scanf函数的话可以先看看博主写的你真的懂scanf函数吗。
简单来说scanf函数就是将标准输入流的数据存储在变量中,因此我们可以理解为
fscanf(stdio,“%d”,&a)等同于scanf(‘%d’,&a),这样你就掌握了这两组函数,同理sscanf函数只是将输入端从文件指针类型变为字符指针类型罢了
如果你懂了上述内容,想必你也会理解如何区分printf,fprintf,sprintf
同理printf函数就是将字符串打印在标准输出流中,因此我们可以理解为
fprintf(stdout,“%d”,&a)等同于scanf(‘%d’,a),这样你就掌握了这两组函数,同理sscanf函数只是将输出端从文件指针类型变为字符指针类型罢了。
有些同学可能没学前还能区分scanf和printf,看完这就不会了。提供给大家一个一劳永逸的方法,就是printf就是将后面的东西存在前面去,scanf就是将前面的东西存在后面去,包括其他两组也是这样的,或者你看到后面的可变参数…中有取地址符号就知道要存到这里去(意思可变参数是一个指针)
fread读取近似scanf就是(前面存到后面)将ptr指向的内存块中count个size字节的内存储存到文件中
fwrite写近似于printf就是(后面存到前面)将文件中count个size字节内容存到ptr指向的内存块中
6.文件的随机读写
6.1 fseek
根据⽂件指针的位置和偏移量来定位⽂件指针(⽂件内容的光标)。
origin有三个
也就是光标会根据你给的起始和偏移量在文件中定位光标
6.2 ftell
6.3 rewind
7.⽂件读取结束的判定
7.1 feof
这个函数经常被人误用它不是用来判断文件结尾的而是用来判断当其他读写函数返回EOF时是因为遇到了错误还是遇到了文件结尾
而判断文件结尾的标志应是
8.文件缓冲区
ANSIC 标准采⽤“缓冲⽂件系统” 处理的数据⽂件的,所谓缓冲⽂件系统是指系统⾃动地在内存中为程序中每⼀个正在使⽤的⽂件开辟⼀块“⽂件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才⼀起送到磁盘上。如果从磁盘向计算机读⼊数据,则从磁盘⽂件中读取数据输⼊到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的⼤⼩根据C编译系统决定的。
#include <stdio.h>
#include <windows.h>
//VS2022 WIN11环境测试
int main()
{
FILE*pf = fopen("test.txt", "w");
fputs("abcdef", pf);//先将代码放在输出缓冲区
printf("睡眠10秒-已经写数据了,打开test.txt⽂件,发现⽂件没有内容\n");
Sleep(10000);
printf("刷新缓冲区\n");
fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到⽂件(磁盘)
//注:fflush 在⾼版本的VS上不能使⽤了
printf("再睡眠10秒-此时,再次打开test.txt⽂件,⽂件有内容了\n");
Sleep(10000);
fclose(pf);
//注:fclose在关闭⽂件的时候,也会刷新缓冲区
pf = NULL;
return 0;
}
因为有缓冲区的存在,C语⾔在操作⽂件的时候,需要做刷新缓冲区或者在⽂件操作结束的时候关闭⽂件。否则读写会出问题也就是数据仅仅在缓冲区上而没有存在在内存中