【C语言】文件操作

目录

前言

一、什么是文件?

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 )。

2.数据文件

文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,
或者输出内容的文件。
我们这篇文章讨论的都是数据文件。

二、文件的打开和关闭

1.文件指针

每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中,该结构体类型是由系统声明的,取名FILE。

也就是说FILE是一个结构体指针类型的变量。我们文件的打开和关闭都是需要FILE的,

我们在文件中每操作一次文件指针就会移动一次:

例如:我们举例,我们创建了test.txt文件,文件中储存了“abcdefghi"这个字符串,我们操作文件指针读取了‘a’操作完成后文件指针后移一位指向'b'。

FILE*是一个文件指针,我们创建一个文件之后,该文件所对应的文件指针就会自动创建在文件信息区,如果打开文件失败,就会返回空指针,与malloc函数类似,所以对于fopen函数,我们也要进行相同操作。

FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
	}

这样能够保证成功的打开了文件,面试官特别喜欢这些判断条件。

2.文件的打开和关闭

我们前面说了这么多,我们要对文件操作首先是需要打开这个文件,可是如何打开文件呢?

这就引出了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<stdio.h>
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程序运行这三个流就默认打开。

2.fputc()函数

写一个字符到流中,第一个变量是要写入的字符,以ASII码的形式储存到流中,

本文主要是有关于文件的操作,因此我们以将字符输入到文件中为例,来演示fputc()函数

#include<stdio.h>
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<stdio.h>
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<stdio.h>
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一次只能获取一个字符,我们连着获取了三次,并且将其储存到变量中,并打印出来

这个例子也证明了文件指针操作函数之后会向后移动。

4.fgets()函数

 有些人可能会说一个一个获取太慢了,有没有函数一次能够获取一行字符,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文件

7.辨析

我们见识过了

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 编译系统决定的。


总结

以上就是今天要分享的内容了。感谢大家的阅读,谢谢。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值