文件的讲解

一、文件的概念

程序文件

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

数据文件

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

文件名

一个文件要有一个唯一的文件标识,以便用户识别和引用。

文件包含 3 部分:文件路径 + 文件名主干 + 文件后缀

比如:c : \ code \ test.txt 。

二、二进制文件和文本文件

根据数据的组织形式,数据文件被称为文本文件和二进制文件。

数据在内存中以二进制的形式存储,如果不加转换的输出到外存的文件中,就是二进制文件。

如果要求在外存上以 ASCII 码值的形式存储,则需要在存储前转换,以 ASCII 字符的形式存储的文件就是文本文件。

存储:

字符一律以 ASCII 码值形式存储,数值型数据既可以用 ASCII 码值形式存储,也可以使用二进制形式存储。

比如有整数 10000,如果以ASCII 码值的形式输出到磁盘,则磁盘中占用 5 个字节(每个字符一个字节),而二进制形式输出,则在磁盘上只占 4 个字节。

三、文件的打开和关闭

文件指针

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

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

文件的打开和关闭

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

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

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

#include<stdio.h>
int main()
{
	FILE* pf = fopen("data.txt", "w");//打开文件
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fclose(pf);//关闭文件
	pf = NULL;
	return 0;
}

fopen 的第二个参数有三种:

w 代表着写文件。

r 代表着读文件。

a 代表着在文件末尾增加数据。

wb 代表着写二进制文件

rb 代表着读二进制文件

fopen 函数如果打开成功,则会返回文件信息区的起始地址,如果打开失败,会返回空指针 NULL。所以,检查返回值就知道文件是否打开成功。

四、文件的顺序读写

函数介绍

fputc 函数

代码:
#include<stdio.h>
int main()
{
	FILE* pf = fopen("data.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char c = 0;
	for (c = 'a'; c <= 'z'; c++)
	{
		fputc(c, pf);
	}
	fclose(pf);
	pf = NULL;
	return 0;
}
运行结果:

fgetc 函数

代码:
#include<stdio.h>
int main()
{
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char ret = 0;
	while ((ret = fgetc(pf)) != EOF)
	{
		printf("%c", ret);
	}
	fclose(pf);
	pf = NULL;
	return 0;
}
运行结果:

fputs 函数

代码:
#include<stdio.h>


int main()
{
	FILE* pf = fopen("data.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fputs("hello world\n", pf);
	fputs("hello everyone\n", pf);
	fclose(pf);
	pf == NULL;

	return 0;
}
运行结果:

fgets 函数

代码:
#include<stdio.h>


int main()
{
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char arr[100] = { 0 };
	while (fgets(arr, 100, pf) != NULL)
	{
		printf("%s", arr);
	}
	fclose(pf);
	pf = NULL;

	return 0;
}
运行结果:

fprintf 函数

代码:
 
#include<stdio.h>


int main()
{
	FILE* pf = fopen("data.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char name[] = "zhangsan", id[] = "20240101";
	int age = 18;
	double score = 80.0;
	fprintf(pf, "%s %s %d %lf", name, id, age, score);
	fclose(pf);
	pf = NULL;

	return 0;
}
运行结果:

fscanf 函数

代码:
 
#include<stdio.h>


int main()
{
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char name[100] = { 0 }, id[100] = { 0 };
	int age = 0;
	double score = 0;
	fscanf(pf, "%s %s %d %lf", name, id, &age, &score);
	printf("%s %s %d %lf\n", name, id, age, score);
	fclose(pf);
	pf = NULL;

	return 0;
}
运行结果:

fwrite 函数

代码:
#include<stdio.h>


int main()
{
	FILE* pf = fopen("data.txt", "wb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int arr[] = { 1,2,3,4,5 };
	fwrite(arr, sizeof(arr[0]), 5, pf);
	fclose(pf);
	pf = NULL;

	return 0;
}
运行结果:

这个是默认编译器,也就是我们正常看到的结果。

用二进制编译器的话就可以看到这种结果。

fread 函数

代码:
#include<stdio.h>


int main()
{
	FILE* pf = fopen("data.txt", "rb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int arr[5] = { 0 }, i = 0;
	while (fread(arr + i, sizeof(arr[0]), 1, pf) != 0)
	{
		printf("%d ", arr[i]);
	}
	fclose(pf);
	pf = NULL;

	return 0;
}
运行结果:

五、文件的随机读写

根据文件指针的位置和偏移量来定位文件指针(文件内容的光标)。

函数介绍

fseek 函数

我们拿 abcdef 来举例。

如果你想要 读到 a 和 d 的话,有三种方法

代码:
#include<stdio.h>


int main()
{
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char ch = fgetc(pf);// a
	printf("%c", ch);
	//fseek(pf, 2, SEEK_CUR);//从当前位置开始定位
	//fseek(pf, 3, SEEK_SET);//从起始位置开始定位
	fseek(pf, -3, SEEK_END);//从末尾位置开始定位
	ch = fgetc(pf);
	printf("%c", ch);
	fclose(pf);
	pf = NULL;
	return 0;
}
运行结果:

ftell 函数

代码:
#include<stdio.h>


int main()
{
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char ch = fgetc(pf);// a
	printf("%c", ch);
	//fseek(pf, 2, SEEK_CUR);//从当前位置开始定位
	//fseek(pf, 3, SEEK_SET);//从起始位置开始定位
	fseek(pf, -3, SEEK_END);//从末尾位置开始定位
	ch = fgetc(pf);
	printf("%c", ch);
	printf("%ld\n", ftell(pf));
	fclose(pf);
	pf = NULL;
	return 0;
}
运行结果:

rewind 函数

代码:
#include<stdio.h>


int main()
{
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char ch = fgetc(pf);// a
	printf("%c", ch);
	//fseek(pf, 2, SEEK_CUR);//从当前位置开始定位
	//fseek(pf, 3, SEEK_SET);//从起始位置开始定位
	fseek(pf, -3, SEEK_END);//从末尾位置开始定位
	ch = fgetc(pf);
	printf("%c", ch);
	printf("%ld\n", ftell(pf));
	rewind(pf);
	ch = fgetc(pf);
	printf("%c", ch);
	fclose(pf);
	pf = NULL;
	return 0;
}
运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值