椋鸟C语言笔记#32:文件、文件指针(流)、文件的打开与关闭

萌新的学习笔记,写错了恳请斧正。


目录

文件标识(文件名)

文件分类

流和标准流的基本概念

标准流

文件指针(C语言中流的实质)

文件的打开和关闭

fclose

fopen

举个栗子


文件标识(文件名)

每个文件都有一个唯一的文件标识,也就是文件名

文件名包含3个部分:文件路径+文件名主干+文件后缀(可省略)

例如:C:\Windows\WindowsUpdate.log

我们常说的“文件名”是指文件名主干

文件分类

文件分为程序文件数据文件

其中数据文件根据数据的组织形式分为文本文件二进制文件

文本文件以ASCII字符的形式存储,二进制文件就是以二进制存储

流和标准流的基本概念

程序往往需要输出到各种外部设备,也需要从外部设备获取数据。为了方便程序员对各种不同设备进行输入输出的调控,就抽象出了流的概念。流可以大概理解为数据传递的一个过程

一般情况下,程序想要输入或输出数据都要先打开对应设备的流,然后在操作

那么为什么我们从键盘上输入数据,向控制台(屏幕)上输出数据时,不需要打开流呢?

这就是因为C语言程序启动时就会默认打开3个流,我们称之为标准流

标准流
  • stdin:标准输入流,大多数环境从键盘输入,scanf函数就是从stdin读取数据
  • stdout:标准输出流,大多数环境输出到控制台,printf函数就是输出数据到stdout
  • stderr:标准错误流,大多数环境输出到显示器界面

这三个流默认打开,其类型为FILE*,通常也称为文件指针

(为什么流会有类型呢?这就是下面要讲的重点了)

在C语言中,我们通过文件指针来维护各种流的操作

文件指针(C语言中流的实质)

ANSIC标准采用“缓冲文件系统”来处理各种数据文件,其中“文件类型指针”(简称“文件指针”)是一个非常重要的概念。

每一个被使用的文件都会在内存中开辟一个相应的文件信息区,用于存放文件的相关信息(文件名主体、状态、路径等等),这些信息被保存在一个结构体变量中,而这个由系统声明的结构体类型就是FILE,比方说某环境下stdio.h中就有这样的声明(不同环境下大同小异):

struct _iobuf {
    char *_ptr;
    int   _cnt;
    char *_base;
    int   _flag;
    int   _file;
    int   _charbuf;
    int   _bufsiz;
    char *_tmpfname;
    };
typedef struct _iobuf FILE;

程序每当打开一个文件,系统就根据文件的情况创建一个FILE类型的结构体变量,并填充其中的信息。而一般我们使用一个FILE*类型的指针来维护这个FILE类型的结构体变量,而这就是我们实现程序与文件之间通讯的基础,也就是C语言中流的实质

文件指针变量可以指向某个文件的文件信息区(一个结构体变量),这样我们就可以通过文件信息区的信息访问和操作文件

文件的打开和关闭

文件在读写前应该先打开,在使用结束后应该关闭

ANSIC规定fopen函数用于打开文件,fclose函数用来关闭文件,原型如下:

#include <stdio.h>
FILE* fopen( const char* filename, const char* mode );
int fclose( FILE* stream );
fclose

fclose函数就是关闭stream指针指向的文件,成功则返回0,失败则返回EOF

关闭文件的实质是:将已经写到输入缓冲区的信息冲入、已经写到输出缓冲区的信息冲出;将尚未写入缓冲区的信息舍弃;最后取消该文件指针与文件的关联

(前两步其实就是刷新缓冲区,缓冲区相关知识下面会讲)

fopen

fopen函数就是以mode模式打开filename指向的文件,并返回一个指向该文件的FILE*指针

如果打开文件失败则返回空指针NULL并设置对应的errno

filename如果包含路径,则会寻找到对应的路径;如果不包含路径,就直接在本目录下(在Windows下表现为在本文件夹下)打开

mode称为文件访问模式字符串,其值与文件打开模式的对应关系如下:

文件访问模式字符串含义解释若文件已存在若文件不存在
"r"只读打开文件以读取从头开始读打开失败报错
"w"只写创建文件以写入销毁内容重写创建新文件
"a"只后附后附到文件从结尾开始写创建新文件
"r+"读扩展打开文件读写从头开始读写打开失败报错
"w+"写扩展创建文件读写销毁内容重新读写创建新文件
"a+"后附扩展打开文件读写

从头开始读

从结尾开始写

创建新文件
标签b:在文件访问模式字符串后加一个b则代表以二进制模式进行(只有Windows下),b是和+类似的后缀所以顺序不影响。比如说:"wb+"和"w+b"都代表创建二进制文件读写,其行为与"w+"也是一样的。
标签t:其实如果没有特意去加标签b,就默认后面有标签t,代表以文本的模式进行。比方说"a+"其实就是"a+t"或者"at+"
后缀x:在基于"w"的文件访问模式字符串的结尾加上x就代表如果文件已经存在的话,不再销毁内容重新写/读写,而是直接认为函数失败并返回NULL

注意:

在更新模式(存在标签"+")下打开文件时:

  • 若中间没有fflush函数或文件定位函数,则输出后不应有输入
  • 若中间没有文件定位函数且输入操作没有遇到文件尾,则输入后不应有输出

(这部分相关的内容后面讲,涉及到缓冲区、文件定位函数等知识。暂且先列在这里,原因后面缓冲区那里再说。)

文件打开的模式与其返回的文件指针的权限息息相关,比如"w"和"a"模式下文件指针是无效的;"w+"和"a+"模式下文件指针只对读有效,如果写,文件指针就会自动移到文件尾

举个栗子

下面就是在本目录下创建一个abc.txt并写入字母表的程序:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("abc.txt", "w");
	if (pf == NULL)
	{
		perror(fopen);
		return 1;
	}
	for (int i = 0; i < 26; i++)
		fputc('a' + i, pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

  • 43
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

椋鸟Starling

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值