C语言文件操作详解(解析各文件函数,如何应用文件函数)

前言:

 

我们为什么要在C语言中引进文件的概念呢?试想一个场景,我们写好了通讯录的源代码运行后录入了联系人的信息,但是每次的操作范围只局限在此次的执行程序中,执行程序一关,联系人的信息随着执行程序在内存中的消失而消失。因此,我们需要把联系人信息保存到硬盘上的话,就需要了文件操作,这就引入了文件。

目录

1、文件的分类

(1)程序文件

   (2)  数据文件

2、文件的打开与关闭

(1)文件指针的介绍

(2)文件的打开与关闭

(3)文件的顺序读写

(4)文件的随机读写

(5)文件缓冲区



1、文件的分类

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

(1)程序文件

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

   (2)  数据文件

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

2、文件的打开与关闭

(1)文件指针的介绍

       缓冲文件系统中,关键的概念是 文件类型指针 ,简称 文件指针
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名 字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统 声明的,取名FILE .
       下面我们可以创建文件指针,如下
FILE* pf
定义 pf 是一个指向 FILE 类型数据的指针变量。可以使 pf 指向某个文件的文件信息区(是一个结构体变 量)。通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联 的文件 。如下图,pf1指针指向f1的文件信息区,便可以访问文件f1的内容,以此类推。

C语言文件操作详解(解析各文件函数,如何应用文件函数)_第1张图片

(2)文件的打开与关闭

通过以上学习对于如何找到文件我们知道了是通过文件指针找到要访问的文件内容。那么如何打开文件呢?这就要介绍下面两个操作文件的函数了:

//打开文件
FILE * fopen ( const char * filename, const char * mode );
//关闭文件
int fclose ( FILE * stream )

这里可见fopen的返回值类型是FILE*型,通常我们写成FILE* pf=FILE*( const char * filename, const char * mode ),用FILE*类型的pf指针接收并打开。

fopen的第一个输入对象是文件名,第二个则是打开类型,有如下的打开类型:

C语言文件操作详解(解析各文件函数,如何应用文件函数)_第2张图片

 

学到这里,我们就能掌握最基础的文件操作,打开关闭了,如例:

#include 
int main ()
{
  FILE * pFile;
  //打开文件
  pFile = fopen ("myfile.txt","w");
  //文件操作
  if (pFile!=NULL)
 {
    fputs ("fopen example",pFile);
    //关闭文件
    fclose (pFile);
 }
  return 0; }

(3)文件的顺序读写

通过以上的学习,我们下面应该学习如何用C语言读写文件内容。这里给出一些最基本的操作函数:

C语言文件操作详解(解析各文件函数,如何应用文件函数)_第3张图片

 下面我给出各个函数使用实例:

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



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

//
//int main()
//{
//	FILE* pf = fopen("tets.txt", "w");
//	if (pf == NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//	fputs("hello", pf);
//	fputs("bitejiuyeke", pf);
//
//
//	fclose(pf);
//	pf = NULL;
//	return 0;
//}


//
//int main()
//{
//	FILE* pf = fopen("tets.txt", "r");
//	if (pf == NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//	//读
//	char arr[] = "***********";
//	fgets(arr, 3, pf);//实际上只读两个,后面放个  \0
//	//,每次只读一行
//	printf("%s", arr);
//
//	fclose(pf);
//	pf = NULL;
//	return 0;
//}
//结构体数据
struct S
{
	char name[20];
	int age;
	float score;
};
//int main()
//{
//	struct S s = { "zhangsan",20,95.5f };
//	//写到文件中
//	FILE* pf=fopen("test.txt","w");
//    if(NULL==pf)
//	{
//		perror("fopen");
//		return 1;
//	}
//	//写文件
//	fprintf(pf, "%s %d %f", s.name, s.age, s.score);
//
//
//	fclose(pf);
//	pf = NULL;
//
//
//	return 0;
//}


//
//int main()
//{
//	struct S s = { "zhangsan",20,95.5f };
//	//写到文件中
//	FILE* pf = fopen("test.txt", "r");
//	if (NULL == pf)
//	{
//		perror("fopen");
//		return 1;
//	}
//	//读文件
//	fscanf(pf, "%s %d %f", &(s.name),&( s.age), &(s.score));
//	printf("%s %d %f\n", s.name, s.age, s.score);
//	return 0;
//
//}

(4)文件的随机读写

上面是文件的顺序读写,那么我们想要读写指定的文件内容该怎么办呢?下面我们介绍随机读写文件的一些函数:

1.fseek

根据文件指针的位置和偏移量来定位文件指针
int fseek(FILE* stream, long int offset, int origin);

第一对象是文件流,第二个是想要访问文件内容的偏移量,第三个是起始位置的描述(起始位置有三个,分别为:SEEK_SET文件起始,SEEK_CUR文件中间,SEEK_END文件末尾),例子如下:

//int main()
//{
//	FILE* pf=fopen("test.txt", "r");
//	if(pf==NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//	//读文件
//	int ch = fgetc(pf);
//	printf("%c\n", ch);
//
//	//SEEK_SET起始
//	//SEEK_CUR中间
//	//SEEK_END末尾
//
//
//	/*fseek(pf, -3, SEEK_END);*/
//	fseek(pf, 2, SEEK_CUR);
//
//	ch = fgetc(pf);
//	printf("%c\n", ch);
//}

2.retell

返回文件指针相对于起始位置的偏移量
long int ftell ( FILE * stream );

返回的是当前文件指针所在文件流的位置。

3.rewind

让文件指针的位置回到文件的起始位置
void rewind ( FILE * stream );

retell,rewind我们借用fseek使用到的代码举例:

//int main()
//{
//	FILE* pf=fopen("test.txt", "r");
//	if(pf==NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//	//读文件
//	int ch = fgetc(pf);
//	printf("%c\n", ch);
//
//	//SEEK_SET起始
//	//SEEK_CUR中间
//	//SEEK_END末尾
//
//
//	/*fseek(pf, -3, SEEK_END);*/
//	fseek(pf, 2, SEEK_CUR);
//
//	ch = fgetc(pf);
//	printf("%c\n", ch);
//
//	int pos = ftell(pf);
//	printf("%d\n", pos);
ftell
返回文件指针相对于起始位置的偏移量
//
//	rewind(pf);
//	ch = fgetc(pf);
//	printf("%c\n", ch);
//
rewind
让文件指针的位置回到文件的起始位置
//	fclose(pf);
//	pf = NULL;
//	return 0;
//}
//
//


(5)文件缓冲区

文件缓冲区是用以暂时存放读写期间的文件数据而在内存区预留的一定空间。通过磁盘缓存来实现,磁盘缓存本身并不是一种实际存在的存储介质,它依托于固定磁盘,提供对主存储器存储空间的扩充,即利用主存中的存储空间, 来暂存从磁盘中读出(或写入)的信息。 主存也可以看做是辅存的高速缓存, 因为,辅存中的数据必须复制到主存方能使用;反之,数据也必须先存在主存中,才能输出到辅存。

#include 
#include 
//VS2013 WIN10环境测试
int main()
{
 FILE*pf = fopen("test.txt", "w");
 fputs("abcdef", pf);//先将代码放在输出缓冲区
 printf("睡眠10秒-已经写数据了,打开test.txt文件,发现文件没有内容\n");
 Sleep(10000);
 printf("刷新缓冲区\n");
 fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到文件(磁盘)
 //注:fflush 在高版本的VS上不能使用了
 printf("再睡眠10秒-此时,再次打开test.txt文件,文件有内容了\n");
 Sleep(10000);
 fclose(pf);
 //注:fclose在关闭文件的时候,也会刷新缓冲区
 pf = NULL;
 return 0; }

C语言文件操作详解(解析各文件函数,如何应用文件函数)_第4张图片

这里可以得出一个 结论
      因为有缓冲区的存在, C 语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文 件。
      如果不做,可能导致读写文件的问题。

      应用文件缓冲区可以很好地提高存储效率。比如,我去问老师问题,我发现一个去问一个,问十几个就要去十几次,但是如果我把问题聚在一起,一次去问十几个问题,老师的办公效率是不是会得到提升呢?

你可能感兴趣的:(c语言,windows,c语言,学习,蓝桥杯)