目录
引入
文件的打开和关闭
文件如何使用程序来打开?
绝对路径需要转义字符
fopen函数
fclose函数
文件的打开方式(fopen第二参数const char* mode):
文件的顺序读写
fgetc和fputc的使用
fputc
fgetc
fgets和fputs的使用
fputs
fgets
perror的使用
fprintf和printf
fscanf和scanf
博主对于输入流和输出流,以及流的理解图
fread二进制的方式读和fwrite二进制的方式写
fwrite二进制的方式写
fread二进制的方式读
函数参数解析
scanf/fscanf/sscanf的区别、printf/fprintf/sprintf的区别
sprintf使用
sscanf使用
序列化和反序列化
文件的随机读写
fseek 文件光标的设置
ftell 计算光标跟起始位置的偏移量
rewind 让文件指针的光标回到起始位置
尾声
引入
在写编程时,例如在终端写入的数据是存放在内存中的,当程序退出后,数据就不存在了。
使用文件可以将数据存到磁盘中,能够做到数据的持久化,这就是为什么要使用文件。
文件分为程序文件和数据文件,程序文件包含例如.c源文件、.obj编译后的目标文件、.exe链接后的可执行文件。数据文件的内容不一定是程序,而是程序运行时需要读写的数据,例如程序通过读数据文件的内容然后赋值到程序中的某个变量。
文件名包含三个部分:文件路径+文件主干名+文件类型,例如c:\code\test.txt,因为test.txt在不同的路径下可能存在相同的名称,可以写相对路径存在的文件名,也可以写绝对路径存在的文件名。
博主认为学习文件操作,利用程序的高效,操作文件内容进行搜索,重复部分修改,循环删除循环添加内容等,操作文件的知识学习后实践下来对我们处理文件更加的迅速高效。
文件的打开和关闭
文件的信息区是一个结构体
VS2013编译环境提供的 stdio.h 头文件中有以下的文件类型申明:
struct _iobuf {
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
};
typedef struct _iobuf FILE;
不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异
文件如何使用程序来打开?
每当打开一个文件就会在内存中开辟一块相应的文件信息区(一个结构体),利用C语言提供的库函数fopen和fclose进行打开一个文件和关闭一个文件。
fopen会返回打开文件开辟的信息区的地址,这个地址类型就是FILE,即返回类型是FILE*,通过这个指针来维护文件。
当然fopen也会失效,例如写一个文件,如果文件不存在,相当于Windows下的新建文件,例如读一个文件,如果文件不存在,当然就会返回NULL指针,所以fopen打开一个文件,FILE*变量接收的返回值要判断是否为空。
绝对路径需要转义字符
----------->>>>>>>>
-------------------------------------------------------------------------------------------------------------------
fopen函数
fopen函数参考
-------------------------------------------------------------------------------------------------------------------
fclose函数
fcolse函数参考
-------------------------------------------------------------------------------------------------------------------
文件的打开方式(fopen第二参数const char* mode):
文件使用方式 | 含义 | 如果指定文件不存在 |
---|---|---|
"r"(只读) | 为了输入数据,打开一个已经存在的文本文件 | 出错 |
"w"(只写) | 为了输出数据,打开一个文本文件 | 建立一个新文件 |
"a"(追加) | 像文本文件尾添加数据 | 建立一个新文件 |
"rb"(只读) | 为了输入数据打开一个二进制文件 | 出错 |
"wb"(只写) | 为了输出数据打开一个二进制文件 | 建立一个新文件 |
"ab"(追加) | 向一个二进制文件尾添加数据 | 出错 |
"r+"(读写) | 为了读和写打开一个文本文件 | 出错 |
"w+"(读写) | 为了读和写建立一个新的文件 | 建立一个新的文件 |
"a+"(读写) | 打开一个文件,在文件尾进行读写 | 建立一个新的文件 |
"rb+"(读写) | 为了读和写打开一个二进制文件 | 出错 |
"wb+"(读写) | 为了读和写新建一个新的二进制文件 | 建立一个新的文件 |
"ab+"(读写) | 打开一个二进制文件,在文件尾进行读和写 | 建立一个新的文件 |
文件的顺序读写
为什么叫做顺序读写?因为光标的移动是按顺序向后走的,例如读一个数据第一次调用库函数读的是第一个字符,第二次调用读的是第二个字符,以此类推。
功能 函数名 适用于
fgetc和fputc的使用
-------------------------------------------------------------------------------------------------------------------
fputc
fputc函数参考
-------------------------------------------------------------------------------------------------------------------
fgetc
fgetc函数参考
-------------------------------------------------------------------------------------------------------------------
fgets和fputs的使用
fputs
fputs函数参考
覆盖因为w,追加使用a
可以通过fputs()的字符串后添加\n进行换行
-------------------------------------------------------------------------------------------------------------------
fgets
fgets函数参考
可以看出读4个字符但是显示3个字符,其实最后一个字符空间是留给'\0'的。
-------------------------------------------------------------------------------------------------------------------
perror的使用
更简洁方便
perror函数参考
区别在于第一种可以拿到字符串信息不打印,第二种会打印
-------------------------------------------------------------------------------------------------------------------
fprintf和printf
fprintf函数参考fprintf函数参考
-------------------------------------------------------------------------------------------------------------------
fscanf和scanf
fscanf函数参考
返回值不用可以不写,提示而已,scanf也一样。
-------------------------------------------------------------------------------------------------------------------
博主对于输入流和输出流,以及流的理解图
从内存中写数据到硬盘上并不是直接写到的,中间会有一个流来助力
因为不同的外部设备它们的读和写不同,C语言的流底层已经实现好了,我们代码玩家不需要去深入了解。
从上面学的FILE*可以传给文件操作函数,其实FILE*就是文件流,我们不是直接的去操作外部设备,是因为有流的介入,例如FILE是一个结构体类型名,可以通过FILE*来维护文件。
C程序只要运行起来默认会打开3个流,stdin(标准输入流-键盘)、stdout(标准输出流-屏幕)、stderror(标准错误流-屏幕),三个类型都是FILE*,即文件流,所以使用printf时因为默认打开的stdout标准输出流会将内容打印在屏幕上。
stdout流的使用展示
-------------------------------------------------------------------------------------------------------------------
fread二进制的方式读和fwrite二进制的方式写
fwrite比如将结构体内存的内容写入到文件中,文件内容以二进制的方式显示,这与字符方式显示不同,fread读取二进制的内容并将其解释成字符内容。
fwrite函数参考
fread函数参考
可以看到函数参数是相同的,看看具体实践。
fwrite二进制的方式写
fread二进制的方式读
函数参数解析
函数参数相同,但是函数关系不同,fwrite是ptr的内容输出到流中,fread是流的内容输入到内存中,字节是size,个数是count。
----------------------------------------------------------------------------------------------------------------------------
scanf/fscanf/sscanf的区别、printf/fprintf/sprintf的区别
''sscanf和sprintf博主认为很牛b''
博主的记忆方式是sscanf(sprintf)和fscanf(fprintf)相似,fscanf是读文件的内容输入到指定的内存中,sscanf是读字符串的数据输入到指定的内存中,fprintf是将指定内存的内容输出到文件中,sprintf是将指定内存的内容输出到字符串中,sscanf和sprintf是格式化的转换,这个就可以将不同类型的数据按照自身的想法将格式化的数据转换到指定的字符串中!
sprintf使用
sprintf函数参考
sscanf使用
sscanf函数参考
序列化和反序列化
从前端获取一个人的个人信息,比如姓名、年龄和分数,获取的是字符串,将字符串交给后端处理,分类赋值给结构体成员。
序列化:把对象转化为可传输的字节序列过程称为序列化。 反序列化:把字节序列还原为对象的过程称为反序列化。
文件的随机读写
文件指针光标的位置,比如光标在文件内容的最左侧,就是文件第一个字符进行读和写。
fseek 文件光标的设置
根据文件指针的位置和偏移量来定位文件指针
offset是偏移量,就是光标的移动次数。origin是已经define定义的标识符常量,分为三个。
SEEK_SET 是文件的起始位置
SEEK_CUR 是文件的当前位置
SEEK_END 是文件的结束位置
向后偏移两次,光标就到了b和c之间,访问的是c
偏移量也可以为负值
ftell 计算光标跟起始位置的偏移量
ftell函数参考
getc获取后光标到达结束位置,ftell计算偏移量
当前光标
起始光标
rewind 让文件指针的光标回到起始位置
rewind函数参考
------------------------------------------------------------------------------------------------------------
尾声
以上就是什么是文件,为什么使用文件,文件的打开和关闭,文件的顺序读写,文件的随机读写涵盖的知识,欢迎大家在评论区留言讨论、补充,让知识更加细化,让内容广为流传,好好学习,天天向上!