文件操作【上篇】

文章目录

  • ️1.为什么使用文件
  • ️2.什么是文件
    • 2.1.程序文件
    • 2.2.数据文件
    • 2.3.文件名
  • ️3.文件的打开和关闭
    • 3.1.文件指针
    • 3.2.文件的打开和关闭
  • ️4.文件的顺序读写
    • 4.1. fputc - 写文件
    • 4.2. fgetc - 读文件
    • 4.3. fputs - 写一行数据
    • 4.4. fgets - 读数据
    • 4.5. fprintf - 格式化的写文件
    • 4.6. fscanf - 格式化的读文件
    • 4.7. 对比一组函数:

在这里插入图片描述

️1.为什么使用文件

我们学习完结构体时,假如需要写一个通讯录的程序,当通讯录运行起来的时候,可以给通讯录中增加,删除数据,此时数据是存放在内存中,当程序退出的时候,通讯录中的数据自然就不存在了,等下次运行通讯录程序的时候,数据又得重新录入,如果使用这样的通讯录就很难受。

我们在想既然是通讯录就应该把信息记录下来,只有我们自己选择删除数据的时候,数据才不复存在。这就涉及到了数据持久化的问题,我们一般数据持久化的方法有:把数据存放在磁盘文件、存放到数据库等方式。

使用文件我们可以将数据直接存放在电脑的硬盘上,做到了数据的持久化。

️2.什么是文件

磁盘上的文件是文件

但是在程序设计中,我们一般谈的文件有两种:程序文件数据文件(从文件功能的角度来分类的)

2.1.程序文件

包括源程序文件(后缀为 .c),目标文件(windows环境后缀为 .obj),可执行程序(windows环境后缀为 .exe)

2.2.数据文件

文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件

2.3.文件名

一个文件要有一个唯一的文件标识,以便用户识别和引用
文件名包含3部分:文件路径+文件名主干+文件后缀
例如:c:\code\test.txt
为了方便起见,文件标识常被称为文件名

️3.文件的打开和关闭

一个经典的问题:把大象装进冰箱需要几步?
文件操作【上篇】_第1张图片
如果想给文件存放数据或者是拿数据和把大象装进冰箱是一样的道理

打开文件 — —> 操作使用(写数据/拿数据) — —> 关闭文件

文件操作【上篇】_第2张图片

3.1.文件指针

缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针

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

不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异的

每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不必关心细节

一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便

文件操作【上篇】_第3张图片
文件操作【上篇】_第4张图片

创建一个 FILE* 的指针变量:

FILE* pf; //文件指针变量

3.2.文件的打开和关闭

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

在编写程序的时候,在打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系

ANSIC规定使用 fopen函数来打开文件,fclose函数来关闭文件

可以参考一下 cplusplus中的资料
在这里插入图片描述
在这里插入图片描述
文件的使用方式:
文件操作【上篇】_第5张图片

️4.文件的顺序读写

文件操作【上篇】_第6张图片
请看代码与注释

int main()
{
	//打开文件
	//相对路径
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件

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

	return 0;
}

执行通过之后,我们看一下后台,
文件操作【上篇】_第7张图片
多出了 test.txt 但是大小为 0KB,因为是空的还没有写入数据

我们写入数据看一下:请看代码与注释

4.1. fputc - 写文件

int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	//把26个字母写到文件里
	int i = 0;
	for (i = 0; i < 26; i++)
	{
		fputc('a' + i, pf);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;

	return 0;
}

执行通过之后看一下后台
文件操作【上篇】_第8张图片

我们读数据看一下:请看代码与注释

4.2. fgetc - 读文件

int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读文件
	int ch = fgetc(pf);
	printf("%c\n", ch);
	//关闭文件
	fclose(pf);
	pf = NULL;

	return 0;
}

文件操作【上篇】_第9张图片
执行通过之后,成功输出了第一个字符

那我们把26个字母都读出来

int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读文件
	int ch = 0;
	int i = 0;
	for (i = 0; i < 26; i++)
	{
		ch = fgetc(pf);
		printf("%c ", ch);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;

	return 0;
}

文件操作【上篇】_第10张图片
可见它是一个一个读取的,这是 fgetc函数独有的功能

我们通过可以参考一下 cplusplus中的资料看一下这两个函数
文件操作【上篇】_第11张图片
文件操作【上篇】_第12张图片
可以了解一下细节

4.3. fputs - 写一行数据

int main()
{
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写一行数据 hello world
	fputs("hello world\n", pf);

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

	return 0;
}

文件操作【上篇】_第13张图片

4.4. fgets - 读数据

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读数据
	char arr[20];
	fgets(arr,5, pf);
	printf("%s\n", arr);

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

	return 0;
}

文件操作【上篇】_第14张图片
只打印了前4个是因为第5个放的是 \0

我们通过可以参考一下 cplusplus中的资料看一下这两个函数
文件操作【上篇】_第15张图片
文件操作【上篇】_第16张图片
可以了解一下细节

4.5. fprintf - 格式化的写文件

struct S
{
	int n;
	float f;
	char arr[20];
};

int main()
{
	struct S s = { 100,3.14f,"zhangsan" };
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	fprintf(pf, "%d %f %s\n", s.n, s.f, s.arr);

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

	return 0;
}

文件操作【上篇】_第17张图片

4.6. fscanf - 格式化的读文件

int main()
{
	struct S s = { 0 };
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读文件
	fscanf(pf, "%d %f %s\n", &(s.n), &(s.f), s.arr);

	printf("%d %f %s\n", s.n,s.f,s.arr);

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

	return 0;
}

文件操作【上篇】_第18张图片
我们通过可以参考一下 cplusplus中的资料看一下这两个函数

fprintf - 格式化的写文件
文件操作【上篇】_第19张图片
文件操作【上篇】_第20张图片

fscanf - 格式化的读文件

文件操作【上篇】_第21张图片
文件操作【上篇】_第22张图片

文件操作【上篇】_第23张图片

读写文件的时候:文件流

C程序默认会打开3个流:
终端设备 - 屏幕:标准输出流 stdout
键盘: 标准输入流 stdin

屏幕: 标准错误流 stderr

stdout stdin stderr 都是FILE*

//比如
	int ch = fgetc(stdin);
	printf("%c\n", ch);

文件操作【上篇】_第24张图片

	fputc('a', stdout);
	fputc('b', stdout); 
	fputc('c', stdout);
	fputc('d', stdout);

文件操作【上篇】_第25张图片

	struct S s = { 1000,3.666f,"hehe" };
	fprintf(stdout,"%d %f %s\n",s.n,s.f,s.arr );

文件操作【上篇】_第26张图片

struct S s = { 0 };
	fscanf(stdin, "%d %f %s", &(s.n), &(s.f), s.arr);
	fprintf(stdout, "%d %f %s\n", s.n, s.f, s.arr);

文件操作【上篇】_第27张图片

4.7. 对比一组函数:

scanf 针对标准输入流(stdin)的格式化的输入函数
printf 针对标准输出流(stdout)的格式化的输出函数

fscanf 针对所有输入流(文件流/stdin)的格式化输入函数
fprintf 针对所有输出流(文件流/stdout)的格式化输出函数

sscanf 把字符串转换成格式化的数据
sprintf 把格式化的数据转换成字符串

struct S
{
	int n;
	float f;
	char arr[20];
};

int main()
{
	struct S s = { 200,3.5f,"wangwu" };
	//把一个结构体转换成字符串
	char arr[200] = { 0 };
	sprintf( arr,"%d %f %s\n",s.n,s.f,s.arr );
	printf("字符串的数据:%s\n", arr);

	//把一个字符串转换成对应的格式化数据
	struct S tmp = { 0 };
	sscanf(arr,"%d %f %s",&(tmp.n), &(tmp.f), tmp.arr);
	printf("格式化的数据:%d %f %s\n", tmp.n, tmp.f, tmp.arr);
	return 0;
}

文件操作【上篇】_第28张图片

今天的内容有些多有些复杂希望烙铁们能够理解喔!

总结
以上就是 文件操作【上篇】 的内容啦
本文章所在【C语言知识篇】专栏,感兴趣的烙铁可以订阅本专栏哦
欲知后事如何,请听下篇分解喽
前途很远,也很暗,但是不要怕,不怕的人面前才有路。
小的会继续学习,继续努力带来更好的作品
创作写文不易,还多请各位大佬uu们多多支持哦

请添加图片描述

你可能感兴趣的:(C语言知识篇,c语言,c++,算法,数据结构,学习方法)