C语言文件操作详解

1. 为什么使用文件

当我们用c语言编写程序时,程序中的数据往往会伴随着程序的结束而被释放,在程序运行的时候,这些数据储存在内存当中,但程序一旦结束,内存被释放,这些数据也就不存在了,这个时候,我想要去将程序中的数据长久的保存下来,我们只要将这些数据保存到电脑的硬盘上,就可以实现数据的持久化了。而文件可以帮助我们把这些数据保存到电脑的硬盘上。

2.什么是文件

很猪脑的一个问题,文件就是磁盘中的文件,分为两种类型,一种是数据文件,一种是程序文件。

2.1 程序文件

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

2.2 数据文件

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

我们处理数据的时候,可以通过键盘输入数据,通过屏幕输出数据。
同时,我们也可以将数据输出到磁盘中,当我们需要使用的时候,再将磁盘中的数据输入到内存中使用,这个就是处理磁盘上的文件。

2.3 文件名称

文件一定要有一个唯一的名称,方便用户识别和使用。
文件名一般包含三部分,文件路径 + 文件名 + 后缀
eg: c:/code/bite.txt
上面的bite就是文件名,(.txt)就是后缀,前面的就是路径。


		那么接下来,我们了解完文件的基本信息之后,就要开始学习如何
		使用文件。
		
		使用文件之前,我们要知道,文件就像是一个水杯,我们使用水杯之
		前要先打开盖子,那打开盖子后,加水还是喝水就都是可以的,用完
		之后也要合起盖子。
		
		文件也是一样,使用之前需要打开文件,使用后还要记得关闭文件。

3.文件的打开和关闭

在学习文件的打开与关闭之前,我们需要了解一个概念:

3.1 文件类型指针

每个被使用的文件都会在内存中开辟一个相应的文件信息区,用来存放文件的相关信息(文件的名称,文件的位置等 )这些信息被放在一个结构体变量中,而这个结构体变量是由系统直接声明的。取名 FILE

每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息.

而我们就可以通过创建一个FILE类型的指针来维护这个FILE结构的变量,这个FILE类型的指针就被我们称为文件类型指针

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

pf1 是一个FILE类型的指针变量,它可以指向某个文件的文件信息区,如下:在这里插入图片描述

3.2 文件的打开与关闭

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

  1. fopen
    在这里插入图片描述
    第一个参数为文件名,当打开成功后,会返回这个文件的初始地址,打开失败返回空指针。
    mode代表读写方式。三种读写方式如下
    在这里插入图片描述
  2. fclose:关闭文件,关闭成功返回0,关闭失败返回EOF。
int main()
{
	FILE* pf;//声明一个文件类型指针用来指向打开的文件
	//文件打开
	pf = fopen("file.txt","w");//打开后,如果打开失败,返回值是空指针,所以一般在fopen的下面要检查一下。
	if (pf == NULL)
	{
		perror(fopen);
		return 1;
	}//检查并且报错

	//写入文件
	fputc();

	//文件关闭
	fclose(pf);
	pf = NULL;//在关闭文件后,开始定义的文件类型指针依旧指向文件,所以需要将这个指针赋值为空指针
	return 0;
}

4. 文件的顺序读写

在这里插入图片描述

4.1 fscanf/fprintf

  1. scanf/printf :适用于标准流的格式化的输入/输出语句。
    就是按照一定的格式从键盘输入数据(scanf),或者按照一定的格式将数据打印到屏幕上(printf)。

  2. fscanf/fprintf :适用于所有流的格式化的输入/输出语句
    它既能按照一定的格式从stdin或者文件输入数据(fscanf),又能按照一定的格式将数据打印到stdout或者文件上。

  3. sscanf :从字符串中按照一定的格式取出格式化的数据

  4. sprintf :将格式化的数据按照一定的格式转化成字符串

PS: fscanf/fprintf 和 sscanf/sprintf 都拥有两个参数,后一个参数是相同的 ,区别在于第一个参数,前者是文件指针,后者是字符指针(指向字符串)。

4.2 fgetc/fputc

在这里插入图片描述
在这里插入图片描述

  1. fgetc:参数是文件指针,可以返回文件指针指向的字符,然后,文件指针前进到下一个字符,如果读取成功,返回读取字符的ASCII码值,读取失败返回EOF。
#include <stdio.h>
int main()
{
	//打开文件
	FILE* pf  = fopen("test.txt", "r");
	if(pf == NULL)
	{
		perror(fopen failed:);
		return 1;
	}
	//读取文件
	char* p = 'weisiyuan';
	fgetc(p);
	

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}
  1. fputc:将字符输入文件,并将文件指针前进一步。
    如果输入成功,返回输入字符的ASCII码值,输入失败返回EOF。

4.3 fgets/fputs

在这里插入图片描述
在这里插入图片描述

  1. fgets:从流(文件或外部设备)中获取字符串,并将其存放到str中,num限制字符串的最大字符数,获取成功返回str的起始地址。

在这里插入图片描述

  1. fputs :将str指向的字符串写入流(文件或者外部设备),从str指向的位置开始写入,直到遇到 ‘\0’ 停止,并且不会将 \0 写入流。而puts会在流的末尾加上换行符( \0 )。
    成功返回非负值,失败返回EOF。

4.4 fread/fwrite

在这里插入图片描述

  1. fread:从流中读取元素数组,存放到ptr指向的空间中,size代表1个元素的大小,单位是字节。count代表的是共读取多少个元素。最后的stream代表流。 最后会返回读取成功的元素个数的总和。

在这里插入图片描述

  1. fwrite:将ptr指向的元素数组写入到流中,size代表元素的大小,单位是字节,count代表元素的个数,stream代表流。
    写入成功返回写入的元素个数总和。

PS:如果上述两个函数的参数size或者count中有值为0,则该函数返回0。

5. 文件的随机读写

5.1 fseek

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

origin有三种如下:

SEEK_SET从文件的初始位置开始计算
SEEK_SUB从文件指针当前的位置开始计算
SEEK_END从文件的末尾开始计算,偏移量一般为负

举个例子:

#include <stdio.h>
int main()
{
	//打开文件
	FILE* pf  = fopen("test.txt", "w");
	if(pf == NULL)
	{
		perror(fopen failed:);
		return 1;
	}
	//写入文件
	char* p = 'weisiyuan';
	fgets(p);
	

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

5.2 ftell

在这里插入图片描述

函数的参数是文件指针
返回值是文件指针当前的偏移量

5.3 rewind


让文件指针的位置返回到文件起始的位置,无返回值。

6.文本文件和二进制文件

数据中内存中是以二进制的形式储存的,当输出到外存的时候,如果没有经过转换,直接输出到外存,就是二进制文件,如果在输出之前,转换成了ascii码值,输出到外存中,就是文本文件。

7.文件读取结束的判定(feof)

feof是用来判断文件读取结束后是读取到了文件末尾结束,还是中途出现错误读取失败结束。
如果feof的返回值为真,则表示这个文件读取到了文件末尾结束。

  1. fgetc:读取成功,返回读取字符的ASCII码值,读取失败,返回EOF
  2. fgets:读取成功,返回读取字符的个数,读取失败,返回NULL
  3. fscanf:读取成功,返回格式串中指定的格式个数,读取失败,返回小于格式串中指定的格式个数。
  4. sread:读取成功,返回要读的元素个数(参数count),读取失败,返回小于要读的元素个数。

代码例子:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>



int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (!pf)
	{
		perror("opening filed:");
		return 0;
	}

	//写入文件
	char* saying = "不知江月待何人";
	if (fputs(saying, pf) == NULL)
	{
		if (feof(pf))
		{
			printf("文件已输入到末尾。");
		}
		else if (ferror(pf))
		{
			printf("I/O error when reading");
		}
	}

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

	return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值