2024年最全C语言的文件操作_使用w文本文件,2024年最新C C++面试题中高级

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

流——一种高度抽象的概念
 生活中存在多种外部设备,比如:文件、屏幕、磁盘等等,每种设备输入输出数据的方式都不一样,为了统一,我们用“流”的方式,来输入输出数据。我们只需要关注流就可以了,不需要关注每种外设的读写,因为底层都是大同小异,经过封装之后显得不同而已,同时也减少了程序猿的负担。

C语言程序只要运行起来,操作系统就默认打开了三个“流”:
分别对应的物理设备有这些
标准输出流:stdout ->屏幕
标准输入流:stdin ->键盘
标准错误流:stderr ->屏幕
它们三个的类型都是FILE*

所以我们可以把信息打印到屏幕上:

//也可以直接输出到屏幕上
int main()
{
	//打印在屏幕上
	fputc('h', stdout);
	fputc('e', stdout);
	fputc('l', stdout);
	fputc('l', stdout);
	fputc('o', stdout);
	printf("\n");
	return 0;
}

在这里插入图片描述
读取数据举例

fgetc

单个字符读取:
在这里插入图片描述

//读取数据
int main()
{
	//打开文件
	FILE\* pf = fopen("data.txt","r");//修改为r,只读的方式
	if (pf == NULL)
	{
		perror("fopen");
		return -1;
	}
	//读写文件
	char ch = fgetc(pf);
	printf("%c\n",ch);
	
	ch = fgetc(pf);
	printf("%c\n", ch);

	ch = fgetc(pf);
	printf("%c\n", ch);
	//将结果打印打屏幕上面去
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

结果展示:
在这里插入图片描述

fgets

行字符读取:
在这里插入图片描述

int main()
{
	//打开文件
	FILE\* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return -1;
	}
	//写文件
	char arr[20] = { 0 };
	fgets(arr,5,pf);
	printf("%s\n",arr);

	fgets(arr, 5, pf);
	printf("%s\n", arr);

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

奇怪的现象:
在这里插入图片描述
奇怪的现象:就是本来读取5个字符,但是却只打印了4个?
原因:我们第五个位置默认填上\0,所以相当于只有4个字符被读了
ps:原来的arr被第二次的读取给覆盖了!

fscanf 格式化输入函数

它只不过比scanf多了一个文件指针参数

//函数原型
int fscanf( FILE \*stream, const char \*format [, argument ]... );

在这里插入图片描述

//fscanf
int main()
{
	//打开文件
	FILE\* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return -1;
	}

	//写文件
	int a =0;
	double d =0;
	fscanf(pf, "%d %lf", &a, &d);

	printf("%d\n",a);
	printf("%lf\n",d);

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

结果展示:
在这里插入图片描述

fprintf 格式化输出函数

它只不过比printf多了一个文件指针参数

//函数原型
int fprintf( FILE \*stream, const char \*format [, argument ]...);

//fscnaf
int main()
{
	//打开文件
	FILE\* pf = fopen("data.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return -1;
	}
	
	//写文件
	int a = 100;
	double d = 3.14;
	fprintf(pf, "%d %lf", a, d);

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

在这里插入图片描述
 上面我们展示的全部都是文本文件,数据文件分为文本文件和二进制文件
文本文件:就是我们能够看懂的
 二进制文件:就是计算机能够看懂的,我们在电脑上显示出来是看不懂的
下面来介绍一下二进制文件的读写:

//函数原型
size_t fwrite( const void \*buffer, size_t size, size_t count, FILE \*stream );

fwrite 二进制输出

//fwrite 二进制写
int main()
{
	//打开文件
	FILE\* pf = fopen("data.txt", "wb");//以wb 二进制的方式写
	if (pf == NULL)
	{
		perror("fopen");
		return -1;
	}

	//写文件
	int arr[5] = { 1,2,3,4,5 };
	fwrite(arr,4,5,pf);

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

结果展示:
在这里插入图片描述

fread 二进制输入

size_t fread( void \*buffer, size_t size, size_t count, FILE \*stream );

虽然二进制文件我们看不懂,但是可以把刚刚写入的数据读出来

//fread 二进制写
int main()
{
	//打开文件
	FILE\* pf = fopen("data.txt", "rb");
	if (pf == NULL)
	{
		perror("fopen");
		return -1;
	}

	int buf[20] = { 0 };
	fread(buf,sizeof(buf),1,pf);
	for (int i = 0; i < sizeof(buf) / sizeof(int); i++)
	{
		printf("%d ",buf[i]);
	}
	printf("\n");
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

结果展示:
在这里插入图片描述

sprintf函数

//sprintf
struct S
{
	int a;
	double d;
	char name[10];
};
int main()
{
	char arr[100] = { 0 };
	struct S s = { 100, 3.14,"zhangsan" };

	//把一个格式化的数据转换为字符串
	sprintf(arr,"%d %lf %s",s.a,s.d,s.name);

	printf("%s\n",arr);
	return 0;
}

在这里插入图片描述

sscanf函数

//sscanf
struct S
{
	int a;
	double d;
	char name[10];
};
int main()
{
	char arr[100] = { 0 };
	struct S s = { 100, 3.14,"zhangsan" };

	//把一个格式化的数据转换为字符串
	sprintf(arr, "%d %lf %s", s.a, s.d, s.name);

	printf("%s\n", arr);

	struct S tmp = { 0 };
	//把一个字符串的数据(arr中)转换为格式化的数据
	sscanf(arr, "%d %lf %s", &(tmp.a), &(tmp.d), tmp.name);

	printf("%d %lf %s\n",tmp.a,tmp.d,tmp.name);
	return 0;
}

在这里插入图片描述
一共有两次打印,第一次打印是按照字符串打印的,第二次是按照结构体数据化的格式打印的。

对比这两组函数:
输入

函数名称功能
scanf从标准输入流(键盘)读取格式化的数据
fsacnf从所有的输入流读取格式化的数据
sscanf从字符串中读取一个格式化的数据 或者说把一个字符串转换成一个格式化的数据

输出

函数名称功能
printf把格式化的数据输出到标准输出(屏幕)上
fprintf把格式化的数据输出到所有输出流(屏幕/文件)上
sprintf把格式化的数据转换成对应的字符串

五、文件的随机读写

5.1 fseek

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

//函数原型
int fseek( FILE \*stream, long offset, int origin );

函数名称fseek
函数功能新定位文件指针的位置
头文件#include<stdio.h>
函数原型int fseek( FILE *stream, long offset, int origin );
参数第一个参数:文件指针第二个参数:偏移量(这个要看origin)第三个参数:起始位置(设置了三个宏 SEEK_CUR SEEK_END SEEK_SET)
返回值如果成功,fseek 返回 0。否则,它将返回非零值。
int main()
{
	FILE\* pf = fopen("data.txt","r");//先人为写入hello数据
	if (pf == NULL)
	{
		perror("fopen");
		return -1;
	}
	//随机读写
	fseek(pf,4,SEEK\_CUR);//定位文件指针
	
	int ch=fgetc(pf);//读取偏移量为4的字符
	printf("%c\n",ch);

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

在这里插入图片描述
结果展示:
在这里插入图片描述

5.2 ftell

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

//函数原型
long ftell( FILE \*stream );

int main()
{
	FILE\* pf = fopen("data.txt","r");
	if (pf == NULL)
	{
		perror("fopen");
		return -1;
	}
	//随机读写
	fseek(pf,4,SEEK\_CUR);//定位文件指针
	
	int ch=fgetc(pf);//读取偏移量为4的字符
	printf("%c\n",ch);

	int a=ftell(pf);//返回偏移量
	printf("%d\n",a);

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

在这里插入图片描述

5.3 rewind

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

void rewind( FILE \*stream );

int main()
{
	FILE\* pf = fopen("data.txt","r");
	if (pf == NULL)
	{
		perror("fopen");
		return -1;
	}
	//随机读写
	fseek(pf,4,SEEK\_CUR);//定位文件指针
	
	int ch=fgetc(pf);//读取偏移量为4的字符
	printf("%c\n",ch);

	int a=ftell(pf);//返回相对于起始位置的偏移量
	printf("%d\n",a);

	rewind(pf);//让文件指针回到起始位置
	a = ftell(pf);//返回相对于起始位置的偏移量
	printf("%d\n", a);

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

在这里插入图片描述

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

根据数据的组织形式,数据文件被称为文本文件或者二进制文件
数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件。
如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。

一个数据在内存中是怎么存储的呢?
字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储
如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而二进制形式输出,则在磁盘上只占4个字节

字符1的ASCII码49,对应的码值是00110001
字符0的ASCII码是48,对应的码值是00110000

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

一个数据在内存中是怎么存储的呢?
字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储
如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而二进制形式输出,则在磁盘上只占4个字节

字符1的ASCII码49,对应的码值是00110001
字符0的ASCII码是48,对应的码值是00110000

[外链图片转存中…(img-Jhba07l9-1715602059711)]
[外链图片转存中…(img-DzJgldjP-1715602059711)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 27
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值