深度理解文件管理(一)

C语言文件管理

文件管理常常作为被忽略知识,但却十分重要,在某些场景缺‘它’不可

1.文件管理有啥用?

  • 我们在写通讯录时候就知道,运行程序时,先输入各种数据,然后调整…,但是当我们结束这个程序时,我们会发现之前存储的那些数据都不在了,然后又要重新输入…,原因是当我们写入数据时,数据保存在内存中,但程序结束后,内存会被电脑回收,数据也就跟着消失了。
  • 将数据存放在文件中就很好解决这个问题,我们都知道文件数据是存放在磁盘文件或数据库中的,这样当程序运行结束后数据也就不会消失了,因此使用文件将数据直接存放在电脑的硬盘上,使得数据的持久化。

在这里插入图片描述

2.什么是文件

  • 磁盘上的文件是文件,文件类型很多,但是在程序设计中,我们一般谈的文件有两种:程序文件、数据文件。

2.1程序文件

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

在这里插入图片描述

2.2数据文件

  • 除了程序文件存放程序外,还有数据文件,存放数据,作为程序运行时读取写入的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。
  • 在以前各章所处理数据的输入输出都是以终端为对象的,比如键盘输入数据,运行结果显示到显示器上,而现在将数据存到文件中,这时候文件就像终端一样,之前键盘输入数据变成从文件中拿数据,之前数据显示在屏幕上变成将数据存到文件中。
    在这里插入图片描述

2.3文件名称

  • 我们每个人有唯一身份证来证明自己独特存在,同理一个文件要有一个唯一的文件标识,以便用户识别和引用。
    文件名包含3部分:文件路径+文件名主干+文件后缀

在这里插入图片描述

3.文件的打开和关闭

3.1文件指针

哎呀,又没见过我不会,好难,我不学了!不要这样,一口吃不成胖子,慢慢吃,就一点也不难。

  • 我们生活中从水壶灌水取水,首先打开水壶,然后在进行取水灌水操作,用完后关闭水壶。同理,使用文件数据拿放时,也得先打开文件,然后进行操作,最后关闭文件。
    在这里插入图片描述
  • 每个被使用的文件都会在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是由系统声明的,取名FILE,由FILE定义指针就是文件指针,指向文件信息区地址。
  • 简单说就是:使用文件时会创建一个文件指针来存放文件一些状态信息,就像我们创建一个变量时可以在创建一个指针存放其地址一样。

我们可以创建一个FILE*的指针变量:

FILE* pf;      /文件指针变量

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

  • 和之前学的指针不能说很相似吧,只能说一模一样

在这里插入图片描述

3.2文件的打开和关闭

  • 刚刚说过文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。
    在编写程序的时候,在打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。ANSIC 规定使用fopen函数来打开文件,fclose来关闭文件。cplusplus网站:fopenfclose
    在这里插入图片描述
  • 常用读取模式:
    在这里插入图片描述

代码实例:


#include <stdio.h>
int main ()
{
  FILE * pFile; /创建文件指针,后面用来接受
  /打开文件
  pFile = fopen ("myfile.txt","w");
  /文件操作
  
  if (pFile!=NULL)  /如果打开失败返回空
 {
    fputs ("fopen example",pFile); /输出数据到文件中
    /关闭文件
    fclose (pFile);
 }
 else
 {
 	perror("fopen:");/错误信息打印,介绍如下,fopen是错误提示词
 }
  return 0;
}

在这里插入图片描述

4.文件顺序读写

  • 常用读写函数如下,在cplusplus网站可以详细学习,我们要学习它的参数,返回值和运用,接下来我会详细演示读写函数。
    在这里插入图片描述

4.1 fputc(),fputc()函数

fput()和fgetc()函数作为单个字符输入输出函数,介绍如下:

在这里插入图片描述

代码演示:

int main()
{
	FILE* pfile; /创建文件指针变量,用于接受fopen返回值
	pfile = fopen("test.txt", "w");  /未写全文件名称,这时会默认在源文件地址下创建
	if (NULL == pfile) /判断是否打开成功(如果没有会自动创建)
	{
		perror("fopen:");  /屏幕上报错
		return;
	}
	fputc('a', pfile);  
	fputc('bc', pfile);  /这样会在文件中写入什么呢?
	fputc('d', pfile); 
	fclose(pfile);  
	pfile = NULL;  /指针置空,防止非法访问
	return 0;
}

实现效果

在这里插入图片描述

  • fgetc()函数

在这里插入图片描述

代码演示:

int main()
{
	FILE* pfile;
	pfile = fopen("test.txt", "r");  /还是刚刚那个文件
	if (NULL == pfile)
	{
		perror("fopen");
		return;
	}
	int i = 0;
	i = fgetc(pfile); /返回值是int型,用int变量接受
	printf("%d ", i);  

	i = fgetc(pfile);
	printf("%c ", i);

	i = fgetc(pfile);
	printf("%d ", i);

	i = fgetc(pfile); /这时已经是文件末尾了,看看会输出什么
	printf("%d ", i);
	fclose(pfile);
	pfile = NULL;
	return 0;
}

实现效果

在这里插入图片描述

4.2 fputs(),fgets()函数

fgets()和fgets()作为行输入输出函数,介绍如下:

在这里插入图片描述

代码演示:

int main()
{
	FILE* pfile;
	/当再次在同一文件进行写入时,之前数据会被销毁,从新开始写入
	pfile = fopen("test.txt", "w");
	if (NULL == pfile)
	{
		perror("fopen");
		return;
	}
	char* arr = "abcdefg";
	fputs(arr, pfile);
	arr = "\nabcd";/文件不会自动换行,要自己手动输入
	fputs(arr, pfile);
	fclose(pfile);
	pfile = NULL;
	return 0;
}

在这里插入图片描述

  • fgets()函数
    在这里插入图片描述
int main()
{
	FILE* pfile;
	pfile = fopen("test.txt", "r");
	if (NULL == pfile)
	{
		perror("fopen");
		return;
	}
	char ptr[20]="########";
	/读一行,读xx个,若没有xx个则文件该行有多少个读多少个
	fgets(ptr, 2, pfile);/无论读多少个实际读数都会少1字符,少那个会放\0
	printf("%s", ptr);
	fgets(ptr, 5, pfile);/读完一行后才会读下一行
	printf("%s", ptr);
	return 0;
}

在这里插入图片描述

4.3 fread()和fwrite()函数

fread(),fwrite()函数作为二进制输入输出(我们看不懂,电脑能看懂)函数,输入输出流只能是文件,用rb和wb,介绍如下:

在这里插入图片描述

代码演示:

/二进制写文件
struct S
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct S s = { "wangwu",18,99.5 };
	FILE* pfile;
	pfile = fopen("test.txt", "wb");
	if (NULL == pfile)
	{
		perror("fopen");
		return;
	}
	fwrite(&s, sizeof(s), 1, pfile);
	fclose(pfile);
	pfile = NULL;
	return 0;
}
/二进制的读文件
struct S
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct S s = { 0 };
	FILE* pfile = 0;
	pfile = fopen("test.txt", "rb");
	if (NULL == pfile)
	{
		perror("fopen");
		return;
	}
	fread(&s, sizeof(s), 1, pfile);
	printf("%s %d %f", s.name, s.age, s.score);
	fclose(pfile);
	pfile = NULL;
	return 0;
}

在这里插入图片描述

4.4 fprintf()和fscanf()函数

  • fprintf(),fscanf()是作为格式化输入输出(结构体)。
  • fprintf,fscanf和我们之前学的printf和scanf是十分相似的,只是对象从键盘和屏幕变成了文件。介绍如下:

在这里插入图片描述

代码演示

/fprintf()函数

struct stu
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct stu s = { "wangwu",19,99.5f};
	FILE* pfile;
	pfile = fopen("test.txt", "w");
	if (NULL == pfile)
	{
		perror("fopen");
		return;
	}
	/和printf区别就是多了一个文件指针参数
	fprintf(pfile,"%s %d %.1f", s.name, s.age, s.score);
	fclose(pfile);
	pfile = NULL;
	return 0;
}

/fscanf()函数

struct stu
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct stu s = {0};
	FILE* pfile;
	pfile = fopen("test.txt", "r");
	if (NULL == pfile)
	{
		perror("fopen");
		return;
	}
	fscanf(pfile, "%s %d %f", s.name, &(s.age), &(s.score));
	printf("%s %d %.1f", s.name, s.age, s.score);
	fclose(pfile);
	pfile = NULL;
	return 0;
}

实现效果:

在这里插入图片描述

5.sscanf和sprintf函数

在这里插入图片描述

代码演示:


struct S
{
	char name[10];
	int age;
	float score;
};

int main()
{
	char arr[100] = { 0 };
	struct S a = { "wangxu",18,99.5 };
	struct S b = { 0 };

	/将结构体转为字符串形式
	sprintf(&arr, "%s ""%d ""%f", a.name, a.age, a.score);
	printf("%s", arr);

	/将arr中字符串转化为结构体形式
	sscanf(&arr, "%s""%d""%f", b.name, &(b.age), &(b.score));
	printf("\n%s ""%d ""%f", b.name, b.age, b.score);
	return 0;
}

在这里插入图片描述

知识补充:

  • fgetc,fputs…是所有输入/输出流,那能不能使用键盘将数据输入到文件,或者将数据打印到屏幕呢?答案是可以的:
    在这里插入图片描述
  • 我们只需要多加入这些流参数就可以实现:scanf(…)等价于fscanf(stdin,…) ,printf等价于fprintf(stdout, …)

代码展示:

/实现在键盘输入,在屏幕打印出来
int main()
{
	int ch = fgetc(stdin);
	fputc(ch, stdout);

	return 0;
}

/实现在键盘输入,打印到文件
int main()
{
	FILE* pfile;
	pfile = fopen("test.txt", "w");
	if (NULL == pfile)
	{
		perror("fopen");
		return;
	}
	fputc(fgetc(stdin), pfile);
	fclose(pfile);
	pfile = NULL;
	return 0;
}

/实现输入到文件变成输入到屏幕
struct stu
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct stu s = { "wangwu",19,99.5f };
	FILE* pfile;
	pfile = fopen("test.txt", "w");
	if (NULL == pfile)
	{
		perror("fopen");
		return;
	}
	/stdout使得原本输入到文件变为可输入到屏幕
	fprintf(stdout, "%s %d %.1f", s.name, s.age, s.score);
	fclose(pfile);
	pfile = NULL;
	return 0;
}
 

实现效果:

在这里插入图片描述

  • 到这里本篇文件管理讲解就结束啦,下一篇将继续讲解接下来内容有:<文件的随机读写 > <文本文件和二进制文件 > <文件读取结束的判定 > <文件缓冲区>这四部分内容。
  • 学习去,冲!!!
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值