C语言 文件操作

本文详细介绍了C语言中文件指针的概念、文件的打开与关闭、读写操作(字符、文本行、格式化、二进制)、以及文件操作中的函数如fopen、fclose、fputc、fgetc、fwrite、fread、sprintf、sscanf等,同时讨论了feof和ferror在文件结束和错误处理中的作用。
摘要由CSDN通过智能技术生成

文件指针

文件指针变量

FILE* p;

定义一个指向FILE类型的指针变量,可以通过这个指针变量找到与之相关的文件。

文件的打开和关闭 

与动态内存类似,文件使用前需要fopen函数打开,试用结束后用fclose函数关闭。

fopen的第一个参数是文件名,第二个参数是文件打开方式,返回一个文件指针。

打开文件有两种方式,一种是文件相对路径,一种是文件绝对路径。

默认当前路径。

FILE* pf = fopen("test.txt", "w");
FILE* pf = fopen(".\\test.txt", "w");//表示这个文件在当前路径下   相对路径 
FILE* pf = fopen("C:\\Users\\86198\\Desktop\\cc文件\\test.txt", "w");//  绝对路径
FILE* pf = fopen("..\\test.txt", "w");//这样可以找到上一层路径下的test文件 相对路径

 文件的建立或打开可能会出错导致文件指针接收不到一个值从而出现野指针,所以需要在文件指针接收后用一个if语句判断文件指针是否成功接收,避免出现野指针的解引用操作。

 

 fclose通过文件指针关闭文件,如果成功关闭则会返回一个0,如果失败则会返回EOF。

#include<stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	fclose(pf);
	pf = NULL;
	return 0;
}

 注意在关闭后将文件指针置空否则会出现野指针。

 当代码运行到13行时,文件已经被关闭了,但是指针pf依旧有值,无法通过这个地址查询到test文件,则pf就会变成野指针。

 文件的顺序读写

 所有输出流包括文件流和标准输出流等。

 

字符输出函数 

 

 

#include<stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//fputc('a', pf);
	//fputc('b', pf);
	//fputc('c', pf);
	//fputc('d', pf);将字符存到文件中
	fputc('a', stdout);
	fputc('b', stdout);
	fputc('c', stdout);
	fputc('d', stdout);
	//将字符通过标准输出流打印到屏幕
	fclose(pf);
	pf = NULL;
	return 0;
}
 字符输入函数

 当读取成功时会返回一个ASCII值,读取失败时会返回一个EOF并设置一个错误提示。

#include<stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int arr = fgetc(pf);
	printf("%c", arr);
	fclose(pf);
	pf = NULL;
	return 0;
}
文本行输出函数

与fputc类似,fputs是将字符串传给流。

文本行输入函数

fgets是从流中获取一个字符串,第一个参数是目标字符串地址,第二个参数是最多接收num-1个字符,第三个参数是流,返回一个字符地址。

 当读到换行或者到了num-1个时就会截至。

格式化输出函数

struct S
{
	float f;
	char c;
	int n;
};
int main()
{
	struct S s = { 3.14f, 'w', 100 };

	FILE* pf = fopen("data.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fprintf(pf, "%f-%c-%d", s.f, s.c, s.n);
	fclose(pf);
	pf = NULL;
	return 0;
}
格式化输入函数

struct S
{
	float f;
	char c;
	int n;
};
int main()
{
	struct S s = {0};
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fscanf(pf, "%f-%c-%d", &(s.f), &(s.c), &(s.n));
	printf("%f-%c-%d\n", s.f, s.c, s.n);
	fclose(pf);
	pf = NULL;
	return 0;
}
二进制输出函数

写一个数据块到流中,把来自ptr的数组中count个数据,每个数据大小为size,写入到stream流中。

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

	return 0;
}
二进制输入函数

int main()
{
	int arr[10] = {0};
	FILE* pf = fopen("data.txt", "rb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fread(arr, sizeof(arr[0]), sizeof(arr) / sizeof(arr[0]), pf);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	fclose(pf);
	pf = NULL;
	return 0;
}
扩展两个函数
sprintf

将格式化的数据转换为字符串

sscanf

将字符串转为格式化数据

struct S
{
	float f;
	char c;
	int n;
};
int main()
{
	struct S s = { 3.14f, 'c', 100 };
	char arr[100] = { 0 };
	sprintf(arr, "%f-%c-%d", s.f, s.c, s.n);
	printf("%s\n", arr);
	struct S tmp = { 0 };
	sscanf(arr, "%f-%c-%d", &(tmp.f), &(tmp.c), &(tmp.n));
	printf("%f\n", tmp.f);
	printf("%c\n", tmp.c);
	printf("%d\n", tmp.n);
	return 0;
}

scanf是格式化的输入函数,针对是标准输入流(键盘)

printf是格式化的输出函数,针对的是标准输出流(屏幕)

fscanf是针对所有输入流(文件流、标准输入流)的格式化输入函数

fprintf是针对所有输出流(文件流、标准输出流)的格式化输出函数

sscanf是将字符串转换为格式化数据

sprintf是将格式化数据转换为字符串

 文件的随机读写

 fseek

根据文件指针的位置和偏移量来定位文件指针

 

函数第一个参数是文件指针,第二个是偏移量可正可负,第三个参数有三个值,第一个SEEK_SET表示文件起始位置,SEEK_CUR表示文件指针当前位置,SEEK_END表示文件末尾位置。

ftell

返回文件指针相对起始位置的偏移量

rewind

让文件指针返回到文件起始位置

文件读取结束的判定

feof

不能用feof的返回值直接判断文件是否结束,而是用于文件读取结束时,判断是读取失败结束,还是遇到文件尾结束。

文本文件读取是否结束,判断返回值是否为EOF(fgetc),或者NULL(fgets)。

二进制文件读取是否结束,判断返回值是否小于实际读取的个数(fread)。

ferror,在文件读取结束后,用来判断文件是否因为读取过程中遇到错误而结束,如果是因为遇到错误结束,会返回一个非0的数。

feof,在文件读取结束后,用来判断文件是否因为读取过程中遇到文件结束标志而结束,如果是文件结束也会返回一个非0的数。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值