C语言 | 文件操作(上)【必收藏】

1、使用文件的原因

首先来看一个代码:

int main()
{
	int a = 0;
	printf("a = %d\n", a);
	scanf("%d", &a);
	printf("a = %d\n", a);
	return 0;
}

当我们输入一个100,代码的运行结果是:
在这里插入图片描述
可以看到,a变成了100,那么我们关闭程序,再次运行程序a还会是100吗?
在这里插入图片描述
a又变为0,这是为什么呢?
原因是: a是在内存上的一块空间,如果程序退出,内存会归还给操作系统,a中的数据就会丢失,所以第二次运行程序时是看不到上一次的数据的,如果我们想要持久化的保存数据,我们可以将数据保存在硬盘上的文件中。

2、什么是文件

磁盘(硬盘)上的文件就是文件
我们一般所说的文件有两种,一种是程序文件,一种是数据文件
程序文件: 源程序文件(后缀为.c),目标文件(Windows环境下的目标文件后缀为.obj),可执行程序(Windows环境下的目标文件后缀为.exe)
数据文件: 文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。
在这里插入图片描述
文件名: 文件路径+文件名主干+文件后缀
例如:c:\code\test.txt
在这里插入图片描述

3、二进制文件和文本文件

根据文件的内容可以将文件划分为二进制文件文本文件
数据是以二进制的补码存储在内存中的,如果不加转换的输出到外存的文件中去,就叫做二进制文件
如果在存储前将数据转换成ASCII值的形式存储到外存中,以ASCII码字符存储的文件就叫做文本文件
举个例子,将 10000 存储到文件中,以二进制形式输出到硬盘上占4个字节,而以ASCII值形式输出则占用5个字节
在这里插入图片描述
代码:

int main()
{
	int a = 10000;
	FILE* p = fopen("data.txt", "wb");//w是写,b是以二进制的形式
	fwrite(&a, 4, 1, p);
	fclose(p);
	p = NULL;
	return 0;
}

结果是一个看不懂的二进制文件
在这里插入图片描述
如果在VS上打开:
在这里插入图片描述
在这里插入图片描述
可以看到存储的是 10 27 00 00,,就是10000
在这里插入图片描述

4、 流的打开与关闭

4.1 流和标准流

4.1.1 流

我们程序的数据需要输出到各种外部设备,也需要从外部设备获取数据,不同的外部设备的输入输出操作各不相同,为了方便程序员对各种设备进行方便的操作,我们抽象出了流的概念,我们可以把流想象成流淌着字符的河。
C程序针对文件、画面、键盘等的数据输入输出操作都是通过流操作的。
一般情况下,我们要想向流里写数据,或者从流中读取数据,都是要打开流,然后操作。

4.1.2 标准流

问题: 在使用C语言写程序时,使用scanf从键盘输入数据或者使用printf向屏幕输出数据为什么没有打开流和关闭流的操作呢?

原因就是C语言程序在启动的时候,默认打开了3个流:
stdin - 标准输入流,在大多数的环境中从键盘输入,scanf函数就是从标准输入流中读取数据。
stdout - 标准输出流,大多数的环境中输出至显示器界面,printf函数就是将信息输出到标准输出 流中。
stderr - 标准错误流,大多数环境中输出到显示器界面。 这是默认打开了这三个流,我们使用scanf、printf等函数就可以直接进行输入输出操作的。
stdin、stdout、stderr 三个流的类型是: FILE* ,通常称为文件指针。
在C语言中,就是通过FILE*的文件指针来维护流的各种操作的。

4.2 文件指针

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

在这里插入图片描述

定义pf是一个指向FILE类型数据的指针变量。可以使pf指向某个文件的文件信息区(是一个结构体变量)。通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够间接找到与它关联的文件。

文件是在硬盘上的,文件信息区是在内存上的!

4.3 文件的打开和关闭

文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。
在编写程序的时候,在打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。
ANSI C 规定使用 fopen 函数来打开文件,fclose 来关闭文件。

//打开文件
FILE * fopen ( const char * filename, const char * mode );
//                  文件名               文件的打开方式

返回的就是FILE*的指针,就是文件信息区的地址,然后就能找到文件信息区,就能找到流,然后进行读写操作

//关闭文件
int fclose ( FILE * stream );

mode表示文件的打开模式,下面都是文件的打开模式:
在这里插入图片描述

代码:

int main()
{
	//打开文件
	//打开成功返回有效的文件指针
	//打开失败返回NULL
	FILE* pf = fopen("data.txt", "w");//只写
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//写文件

	//关闭文件
	fclose(pf);
	pf = NULL;

	return 0;
}

在这里插入图片描述
若文件路径下没有data.txt的文件,在只写的情况下,会自动在文件路径下创建一个data.txt文件,然后可以进行文件的写操作

若文件路径下有data.txt文件,并且文件中有内容,在只写的情况下会清空文件中的内容

执行程序前:
在这里插入图片描述
执行程序后:
在这里插入图片描述

代码:举例“w”和“r”

int main()
{
	//打开文件
	//打开成功返回有效的文件指针
	//打开失败返回NULL
	FILE* pf = fopen("test.txt", "r");//只读
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读文件

	//关闭文件
	fclose(pf);
	pf = NULL;

	return 0;
}

在这里插入图片描述
文件路径下没有test.txt文件,只读的话会报错
在这里插入图片描述
假如文件现在不在当前程序的路径下,在桌面该怎么打开?

我们就需要再在文件名之前添加文件的路径,如果能找到该文件,则文件内容会被清空
在这里插入图片描述
代码:

int main()
{
	//打开文件
	//打开成功返回有效的文件指针
	//打开失败返回NULL
	FILE* pf = fopen("C:\\Users\\Administrator\\Desktop\\test.txt", "w");//只写
	//                这也叫做绝对路径
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//写文件

	//关闭文件
	fclose(pf);
	pf = NULL;

	return 0;
}

若文件在该工程所在路径的上一级路径该怎么办?
在这里插入图片描述

int main()
{
	//打开文件
	//打开成功返回有效的文件指针
	//打开失败返回NULL
	FILE* pf = fopen(".\\..\\test.txt", "w");
	//这叫做相对路径
	//. 表示当前路径
	//.. 表示上一级路径
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//写文件

	//关闭文件
	fclose(pf);
	pf = NULL;

	return 0;
}

在这里插入图片描述
文件被清空,说明文件操作成功!

5、文件的顺序读写

5.1 顺序读写函数介绍

在这里插入图片描述

上面说的适用于所有输入流一般指适用于标准输入流和其他输入流(如文件输入流);
所有输出流一般指适用于标准输出流和其他输出流(如文件输出流)。

5.1.1 fputc与fgetc

fputc:

int fputc ( int character, FILE * stream );
//            输入的内容      文件指针

代码:

int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	for (int i = 'a'; i <= 'z'; i++)
	{
		fputc(i, pf);
		//  内容  文件指针
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

程序执行结果:项文件中写入26个英文字母
在这里插入图片描述

fgetc:

int fgetc ( FILE * stream );
//            文件指针

若文件读取成功,返回字符的ASCII值;
若文件读取失败,返回EOF(文件结束标志);

int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	int ch = 0;
	while ((ch = fgetc(pf)) != EOF)
	{
		printf("%c ", ch);
	}

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

程序执行结果:
在这里插入图片描述

以上就是上篇的全部内容啦!下篇更精彩哦!希望大家多多点赞支持!
如果有什么问题,欢迎私信!
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值