浅谈C语言中的文件以及文件操作
1.C语言中的文件介绍
1.1文件的介绍
1广义上来说文件就是字节序列,仅此而已。每个 I/0 设备,包括磁盘、键盘、显示器,甚至网络,都可以看成是文件 。这就把文件的定义范化了。
狭义上来讲,我们讲磁盘上的文件就是文件了。C语言中的文件也可以按此来理解。
1.2为什么使用文件
我们写的程序的数据是存储在电脑的内存中,如果程序退出,内存回收,数据就丢失了,等再次运⾏程序,是看不到上次程序的数据的。如果要将数据进⾏持久化的保存,我们可以使⽤⽂件来存储我们的程序数据。
1.3C语言文件的分类
我们按照功能角度可以将文件划分为:1.程序文件;2.数据文件
程序文件:它包括、源程序⽂件(后缀为.c),⽬标⽂件(windows环境后缀为.obj),可执⾏程序(windows环境后缀为.exe)。
数据文件:⽂件的内容不⼀定是程序,⽽是程序运⾏时读写的数据,⽐如程序运⾏需要从中读取数据的⽂件,或者输出内容的⽂件。我们接下来操作的文件都指的是数据文件。因为操作数据文件就是我们对磁盘中的数据进行操作,这也是我们日常操作经常使用的功能。
1.4文件名
文件名包三部分:文件路径+文件名主干+文件后缀
例如:
c:\code\test.txt
一般情况,我们把文件名主干+文件后缀称之为文件名。
2.C语言中的文件操作
2.1流和标准流
2.1.1流
2我们程序的数据需要输出到各种外部设备,也需要从外部设备获取数据,不同的外部设备的输⼊输出操作各不相同,为了⽅便程序员对各种设备进⾏⽅便的操作,我们抽象出了流的概念,我们可以把流想象成流淌着字符的河。
C程序针对⽂件、画⾯、键盘等的数据输⼊输出操作都是同流操作的。
⼀般情况下,我们要想向流⾥写数据,或者从流中读取数据,都是要打开流,然后操作。
2.1.2标准流
2C语⾔程序在启动的时候,默认打开了3个流:
• stdin-标准输⼊流,在⼤多数的环境中从键盘输⼊。
• stdout-标准输出流,⼤多数的环境中输出⾄显⽰器界⾯。
• stderr-标准错误流,⼤多数环境中输出到显⽰器界⾯。
stdin、stdout、stderr三个流的类型是: FILE* ,通常称为⽂件指针。
C语⾔中,就是通过 FILE* 的⽂件指针来维护流的各种操作的。
2.2文件指针
每个被使⽤的⽂件都在内存中开辟了⼀个相应的⽂件信息区,⽤来存放⽂件的相关信息(如⽂件的名字,⽂件状态及⽂件当前的位置等)。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系统声明的,取名FILE.
我们可以创建一个FILE*的指针变量:
FILE* pf
定义pf是⼀个指向FILE类型数据的指针变量。可以使pf指向某个⽂件的⽂件信息区(是⼀个结构体变量)。通过该⽂件信息区中的信息就能够访问该⽂件。也就是说,通过⽂件指针变量能够间接找到与它关联的⽂件。
2.3文件的打开和关闭
ANSIC规定使⽤ fopen 函数来打开⽂件, fclose 来关闭⽂件。
我们先来看看3fopen函数:
FILE * fopen ( const char * filename, const char * mode );
//filename指的是文件名,而mode指的是访问的模式
2mode的值如下:
模式 | 描述 | 如果指定⽂件不存在 |
---|---|---|
“r”(只读) | 为了输⼊数据,打开⼀个已经存在的⽂本⽂件 | 出错 |
“w”(只写) | 为了输出数据,打开⼀个⽂本⽂件 | 建⽴⼀个新的⽂件 |
“a”(追加) | 向文本文件末尾添加数据 | 建⽴⼀个新的⽂件 |
“rb”(只读) | 为了输入数据,打开一个二进制文件 | 出错 |
“wb”(只写) | 为了输出数据,打开一个二进制文件 | 建⽴⼀个新的⽂件 |
“ab”(追加) | 向一个二进制文件尾添加数据 | 建立一个新的文件 |
“r+”(读写) | 为了读和写 ,打开一个文本文件 | 出错 |
“w+”(读写) | 为了读和写,建立一个新的文件 | 建立一个新的文件 |
“a+”(读写) | 打开一个文件,在文件尾进行读写 | 建立一个新的文件 |
“rb+”(读写) | 为了读和写打开⼀个⼆进制⽂件 | 出错 |
“wb+”(读写) | 为了读和写,新建⼀个新的⼆进制⽂件 | 建⽴⼀个新的⽂件 |
“ab+”(读写) | 打开⼀个⼆进制⽂件,在⽂件尾进⾏读和写 | 建立一个新的文件 |
大家可以尝试如下的代码,取消注释观察自己文件操作的结果如何:
#include <stdio.h>
int main()
{
//FILE* fp = fopen("text.txt", "w");//只写 选取好对应的模式
//FILE* fp = fopen("text.txt", "r");//只读
//FILE* fp = fopen("text.txt", "a");//追加
//FILE* fp = fopen("text.txt", "rb");//只读 二进制
FILE* fp = fopen("text.txt", "wb");//只写 二进制 重新写入
//FILE* fp = fopen("text.txt", "ab");//追加 二进制
//FILE* fp = fopen("text.txt", "r+");//读写
//FILE* fp = fopen("text.txt", "w+");//读写
//FILE* fp = fopen("text.txt", "a+");//读写 追加
//FILE* fp = fopen("text.txt", "rb+");//读写
//FILE* fp = fopen("text.txt", "wb+");//读写
//FILE* fp = fopen("text.txt", "ab+");//读写
if (fp != NULL)
{
fputs("fopen example", fp);//将内容传递到文件中去
fclose(fp);//关闭文件
fp=NULL;//防止内存泄露
}
else
{
perror(fopen);
}
return 0;
}
2.4文件的顺序读写
2顺序读写的函数有:
函数名 | 功能 | 适用于 |
---|---|---|
fgetc | 字符输入函数 | 所有输入流 |
fputc | 字符输出函数 | 所有输出流 |
fgets | 文本行输入函数 | 所有输出流 |
fputs | 字符输出函数 | 所有输出流 |
fscanf | 格式化输入函数 | 所有输入流 |
fprintf | 格式化输出函数 | 所有输出流 |
fread | 二进制输入 | 文件 |
fwrite | 二进制输出 | 文件 |
这就不上代码了,具体每一个函数建议都去www.cplusplus.com(进入legacy version)去搜索具体如何使用以及使用效果。要注意每个函数要与对应的fopen函数中的不同mode去配合。
2.5随机读写函数介绍
2.5.1 fseek
int fseek ( FILE * stream, long int offset, int origin );
功能是根据文件指针的位置和偏移量来定位文件指针。
2.5.2 rewind
void rewind ( FILE * stream );
功能是让⽂件指针的位置回到⽂件的起始位置。
2.5.3 ftell
long int ftell ( FILE * stream );
返回⽂件指针相对于起始位置的偏移量