目录
前言
一、什么是文件?
1.程序文件
2.数据文件
二、文件的打开和关闭
1.文件指针
2.文件的打开和关闭
3.fopen()函数
4.fclose()函数
三、文件的顺序读写
1.基本概念
2.fputc()函数
3.fgetc()函数
4.fgets()函数
5.feof()函数
6.其它函数
7.辨析
四、文件的随机读写
1.fseek()函数
2.ftell()函数
3.rewind()函数
五、文件缓冲区
总结
前言
我们前面写过扫雷,三子棋,通讯录等项目,但是我们发现这些项目都只能运行一次之后,所有的数据就都丢失了,通讯录无法保存上一次储存的联系人,要想解决这个问题,我们就需要了解文件 *** 作。
提示:以下是本篇文章正文内容,下面案例可供参考
一、什么是文件?
所谓“文件”,就是在我们的电脑中,以实现某种功能、或某个软件的部分功能为目的而定义的一个单位。
文件有很多种,运行的方式也各有不同。
一般来说我们可以通过文件名来识别这个文件是哪种类型,特定的文件都会有特定的图标(就是显示这个文件的样子),也只有安装了相应的软件,才能正确显示这个文件的图标。
文件是与软件研制、维护和使用有关的资料,通常可以长久保存。
文件是 软件 的重要组成部分。
在软件产品研制过程中,以书面形式固定下来的用户需求、在研制周期中各阶段产生的规格说明、研究人员作出的决策及其依据、遗留问题和进一步改进的方向,以及最终产品的使用手册和 *** 作说明等,都记录在各种形式的文件档案中。
----以上来自百度百科
我们所说的文件主要包含两种
1.程序文件 包括源程序文件(后缀为 .c ) , 目标文件( windows 环境后缀为 .obj ) , 可执行程序( windows 环境 后缀为 .exe )。我们这篇文章讨论的都是数据文件。
二、文件的打开和关闭 1.文件指针
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。
这些信息是保存在一个结构体变量中,该结构体类型是由系统声明的,取名FILE。
也就是说FILE是一个结构体指针类型的变量。
我们文件的打开和关闭都是需要FILE的,
我们在文件中每 *** 作一次文件指针就会移动一次:
例如:我们举例,我们创建了test.txt文件,文件中储存了“abcdefghi"这个字符串,我们 *** 作文件指针读取了‘a’ *** 作完成后文件指针后移一位指向'b'。
FILE*是一个文件指针,我们创建一个文件之后,该文件所对应的文件指针就会自动创建在文件信息区,如果打开文件失败,就会返回空指针,与malloc函数类似,所以对于fopen函数,我们也要进行相同 *** 作。
FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen");
}
这样能够保证成功的打开了文件,面试官特别喜欢这些判断条件。
我们前面说了这么多,我们要对文件 *** 作首先是需要打开这个文件,可是如何打开文件呢?
这就引出了fopen()函数
3.fopen()函数fopen函数一共有两个参数,第一个参数顾名思义就是要打开的文件的名字,它是const char*类型的变量,而第二个参数就有点复杂了。
下面表格是fopen函数的最后一个参数
文件使用方式 | 含义 | 如果指定文件不存在 |
“r”(只读) | 为了输入数据,打开一个已经存在的文本文件 | 出错 |
“w”(只写) | 为了输出数据,打开一个文本文件 | 建立一个新的文件 |
“a”(追加) | 向文本文件尾添加数据 | 建立一个新的文件 |
“rb”(只读) | 为了输入数据,打开一个二进制文件 | 出错 |
"wb"(只写) | 为了输出数据,打开一个二进制文件 | 建立一个新的文件 |
“ab”(追加) | 向一个二进制文件尾添加数据 | 出错 |
“r+”(读写) | 为了读和写,打开一个文本文件 | 出错 |
“w+”(读写) | 为了读和写,建议一个新的文件 | 建立一个新的文件 |
“a+”(读写) | 打开一个文件,在文件尾进行读写 | 建立一个新的文件 |
“rb+”(读写) | 为了读和写打开一个二进制文件 | 出错 |
“wb+”(读写) | 为了读和写,新建一个新的二进制文件 | 建立一个新的文件 |
“ab+”(读写) | 打开一个二进制文件,在文件尾进行读和写 | 建立一个新的文件 |
我们要注意,fopen函数最后一个参数要加上” “双引号,切记不要忘记。
fopen函数我们主要掌握加粗的就可以了。
fopen返回的是一个文件指针,这个指针是指向文件信息区的起始地址,“w”以写的形式,如果不存在该文件就创建一个文件,如果已存在就会销毁该文件,再重新创建一个文件。
fopen函数可以跨文件打开文件,也就是说,我们通常创建的文件会在我们代码存放的路径下创建文件如:
test.txt就是fopen所创建的文件。
跨文件 *** 作的话就需要写上文件的绝对路径,如
这就是绝对路径。
切记:文件名中有一些禁止使用的字符
文件名可以不包含后缀名
文件的后缀名决定了一个文件的默认打开方式
文件的路径是从盘符到该文件所经历的路径中各符号名的集合
4.fclose()函数上面我们介绍了打开文件的 *** 作,既然文件可以打开,那么必然也可以将文件关闭。
fclose就是将文件关闭的函数。
fclose函数与free函数相似,我们只需要传入文件指针就可以了
fclose如果成功关闭文件就会返回0,我们关闭文件之后,需要把文件指针置为NULL,原因与指向malloc创建的空间的指针被free之后的原因相似,避免出现非法访问,我们虽然关闭了文件,但是文件指针的指向没有改变,很容易就会出现非法访问。
#include
int main()
{
FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen");
}
fclose(pf);
pf = NULL;
return 0;
}
上面我们只进行了文件的打开与关闭,在打开之后,我们就需要 *** 作文件,然后关闭文件,这是标准的流程,下面我们介绍文件 *** 作函数
三、文件的顺序读写 1.基本概念
我们首先要明确一个概念,什么是流?
计算机中的流可以看作水流,我们计算机的外部设备有很多(键盘,鼠标,屏幕,U盘,网卡)等,我们编写程序对于不同的外部设备可能输入输出的方式不对,我们不可能针对每一种设备都掌握它的输入输出方式,因此就有了流的概念。
我们只需要从流中获取数据,或者将数据放在流中就可以了。
我们主要来说文件流
标准输入流 | stdin | 键盘 |
标准输出流 | stdout | 屏幕 |
标准错误流 | stderr | 屏幕 |
它们都是FILE*类型的指针,只要C程序运行这三个流就默认打开。
写一个字符到流中,第一个变量是要写入的字符,以ASII码的形式储存到流中,
本文主要是有关于文件的 *** 作,因此我们以将字符输入到文件中为例,来演示fputc()函数
#include
int main()
{
//打开文件
FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen");
}
// *** 作文件
fputc('a', pf);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
编译没有出错,接下来我们打开test.txt文件
文件中就有了a,我们可以写一个循环将26个字母传入文件中
#include
int main()
{
//打开文件
FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen");
}
// *** 作文件
char ch = 'a';
for (ch = 'a'; ch <= 'z'; ch++)
{
fputc(ch, pf);
}
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
3.fgetc()函数
从一个流中读取一个字符,前面我们使用fgetc函数将字符传入到文件中,同理我们也可以从文件中读取字符到变量中
前面我们的test.txt文件中已经有a`z地字符了,我们用fgetc来获取字符
#include
int main()
{
//打开文件
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
}
// *** 作文件
char ch1 = fgetc(pf);
char ch2 = fgetc(pf);
char ch3 = getc(pf);
printf("%c\n%c\n%c\n", ch1, ch2, ch3);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
fgetc一次只能获取一个字符,我们连着获取了三次,并且将其储存到变量中,并打印出来
这个例子也证明了文件指针 *** 作函数之后会向后移动。
有些人可能会说一个一个获取太慢了,有没有函数一次能够获取一行字符,fgets()函数就能够做到这一点。
fgets函数是用来读取某个流中的数据到数组中,第一个参数是要传入的数组的地址,最后一个文件指针就是要从哪个文件传入的流,我们单独说中间地变量n.
n是要传入数据的最大个数,它的单位是字节,假如我们传入n,实际上它只能最多传入n-1个数据
如果文件结束或者出错就会返回NULL
如果不知道文件中有多少行,可以这样来解决
while(fgets(arr,256,pf)!=EOF)
{
printf("%s",arr);
}
5.feof()函数
我们接着fgets()函数文件结束或者出错返回NULL这一条来说的,在网上有一种错误的认知
有人说feof是用来判断文件否读完的函数,实际上feof是在读取结束判断是什么原因使fgets函数返回NULL的
1. 文本文件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets ) 例如: fgetc 判断是否为 EOF . fgets 判断返回值是否为 NULL . 2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。
例如: fread 判断返回值是否小于实际要读的个数 6.其它函数
功能 | 函数名 | 适用于 |
字符输入函数 | fgetc | 所有输入流 |
字符输出函数 | fputc | 所有输出流 |
文本行输入函数 | fgets | 所有输入流 |
文本行输出函数 | fputs | 所有输出流 |
格式化输入函数 | fscanf | 所有输入流 |
格式化输出函数 | fprintf | 所有输出流 |
二进制输入 | fread | 文件 |
二进制输出 | fwrite | 文件 |
我们见识过了
scanf printf
fscanf fprintf
sscanf ssprintf
这几组函数的不同
scanf是格式化输入函数
printf是格式化输出函数
fscanf是针对所有流的格式化输入函数
fprintf是针对所有流的格式化输出函数
sscanf是把一个字符串转化成格式化的数据
sprintf是把一个格式化的数据转化成字符串
四、文件的随机读写 1.fseek()函数
根据文件指针的位置和偏移量来定位文件指针,这个函数比较简单,第一个参数是流,第二个参数是将第一个参数移动几个单位,第三个参数比较特殊
这三个就是最后一个参数
SEEK_CUR是当前文件指针的位置
SEEK_SET是文件开始位置
SEEK_END是文件结束位置
2.ftell()函数
这个函数比较简单,就是返回文件指针的偏移量
3.rewind()函数
是将文件指针返回到起始位置
我们通过fseek也可以做到这点,fsekk(pf,0,SEEK_SET)
就让函数指针回到起点了
五、文件缓冲区
ANSIC 标准采用 “ 缓冲文件系统 ” 处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序 中每一个正在使用的文件开辟一块 “ 文件缓冲区 ” 。
从内存向磁盘输出数据会先送到内存中的缓冲区,装
满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓
冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根
据 C 编译系统决定的。
总结
以上就是今天要分享的内容了。
感谢大家的阅读,谢谢。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)