C语言-文件操作(13.1)

news2024/12/23 16:22:41

目录

思维导图:

1. 为什么使用文件

2. 什么是文件

2.1 程序文件

2.2 数据文件

2.3 文件名

3. 文件的打开和关闭

3.1 文件指针

3.2 文件的打开和关闭

4. 文件的顺序读写

4.1 对比一组函数

5. 文件的随机读写

5.1 fseek

5.2 ftell

5.3 rewind

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

7. 文件读取结束的判定

7.1 feof

8. 文件缓冲区

写在最后:


思维导图:

1. 为什么使用文件

在学习通讯录的时候,我们往通讯录里添加信息,

但是,当我们关闭程序的时候,存放在通讯录的内容就销毁了。

而使用文件我们可以将数据直接存放在电脑的硬盘上,做到了数据的持久化。

如果把通讯录数据放文件了,下一次打开也能继承上一次的数据。

2. 什么是文件

磁盘上的文件就是文件。

但是在程序设计中,我们一般谈的文件有两种:程序文件和数据文件。

2.1 程序文件

程序文件包括:

1.源程序文件(后缀为.c)

2.目标文件(windows环境后缀为.obj)

3.可执行程序(windows环境后缀为.exe)

2.2 数据文件

 文件的内容不一定是程序,而是程序运行时读写的数据,

比如程序运行需要从中读取数据的文件,或者输出内容的文件。

2.3 文件名

一个文件有一个唯一的文件标识,

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

例: c:\code\test.txt

3. 文件的打开和关闭

3.1 文件指针

在C语言中,我们需要知道的是 FILE* 是文件类型的指针,

他的具体实现是C语言已经帮我们实现了的。

3.2 文件的打开和关闭

文件的打开使用的是 fopen 函数:

 

 文件的关闭使用的是 fclose 函数:

 

直接上代码:

例:

int main()
{
    //打开并读取这个文件名的文件
	FILE* pf = fopen("test.txt", "r");

    //判断打开文件是否成功
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读文件

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

输出:

输出;fopen: No such file or directory

因为磁盘中并没有这个文件,所以报错。

对文件的操作还有很多:

文件使用方式含义如果指定文件不存在
“r”(只读)为了输入数据,打开一个已经存在的文本文件出错
“w”(只写)为了输出数据,打开一个文本文件建立一个新的文件
“a”(追加)向文本文件尾添加数据建立一个新的文件
“rb”(只读)为了输入数据,打开一个二进制文件出错
“wb”(只写)为了输出数据,打开一个二进制文件建立一个新的文件
“ab”(追加)向一个二进制文件尾添加数据出错
“r+”(读写)为了读和写,打开一个文本文件出错
“w+”(读写)为了读和写,建议一个新的文件建立一个新的文件
“a+”(读写)打开一个文件,在文件尾进行读写建立一个新的文件
“rb+”(读写)为了读和写打开一个二进制文件出错
“wb+”(读写)为了读和写,新建一个新的二进制文件建立一个新的文件
“ab+”(读写)打开一个二进制文件,在文件尾进行读和写建立一个新的文件

之后再用到的时候需要对其一定的了解。

4. 文件的顺序读写

接下来我们学习一些对文件读写的函数,

这样我们才能更好的操作文件。

功能函数名适用于
字符输入函数fgetc所有输入流
字符输出函数fputc所有输出流
文本行输入函数fgets所有输入流
文本行输出函数fputs所有输出流
格式化输入函数fscanf所有输入流
格式化输出函数fprintf所有输出流
二进制输入fread文件
二进制输出fwrite文件

 我们通过一些例子来学习一下上述函数:

字符输出函数 fputc:

例1:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	
	//写文件
	fputc('a', pf);
		
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

我们先通过 fputc 函数写了个字符‘a’进文件test.txt中。

打开文件:

 文件中真的写入了字符‘a’。

字符输入函数 fgetc:

 

我们还能通过 fgetc 函数读文件验证一下:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读文件
	int ch = fgetc(pf);
	printf("%c\n", ch);
		
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

输出:

 我们发现真的读出并打印出了字符‘a’。

接下来我们学习一下 fputs 函数和 fgets 函数。

 

例:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//写文件
	fputs("welcome to my blog\n", pf);
	fputs("happy new year\n", pf);

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

输出:

写完文件之后,自然是读出来看看:

 

 

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读文件
	char buf[20] = { 0 };
	fgets(buf, 20, pf);//只读一行
	printf("%s\n", buf);

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

我们发现 fgets 函数只读一行:

 只要我们再用一次 fgets 函数就行:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读文件
	char buf[20] = { 0 };
	fgets(buf, 20, pf);//只读一行
	printf("%s", buf);

	fgets(buf, 20, pf);
	printf("%s", buf);

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

输出:

 接下来是 fprintf 函数,格式化写入文件:

 例:

#include <stdio.h>

typedef struct S
{
	char name[20];
	int age;
	float score;
}S;

int main()
{
	S s = { "zhagnsan",120,2.22 };

	S* ps = &s;

	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//格式化写入文件
	fprintf(pf, "%s %d %f\n", ps->name, ps->age, ps->score);

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

输出:

 文件成功写入了,

接下来是格式化输出 fscanf 函数:

例:

#include <stdio.h>

typedef struct S
{
	char name[20];
	int age;
	float score;
}S;

int main()
{
	S s = { "zhagnsan",120,2.22 };
	S* ps = &s;

	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//格式化的读文件
	fscanf(pf, "%s %d %f", ps->name, &(ps->age), &(ps->score));
	printf("%s %d %f\n", ps->name, ps->age, ps->score);

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

 输出:

 最后是二进制写入文件 fwrite 函数:

 

#include <stdio.h>

typedef struct S
{
	char name[20];
	int age;
	float score;
}S;

int main()
{
	S s = { "zhagnsan",120,2.22 };
	S* ps = &s;
	FILE* pf = fopen("test.txt", "wb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//写文件
	fwrite(&s, sizeof(S), 1, pf);

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

输出:

 因为写进去的是二进制的形式,所以就出现了一些你看不懂的东西。

接着,我们用二进制的形式读取文件 fread 函数:

#include <stdio.h>

typedef struct S
{
	char name[20];
	int age;
	float score;
}S;

int main()
{
	S s = { "zhagnsan",120,2.22 };
	//S s = {0};
	S* ps = &s;
	FILE* pf = fopen("test.txt", "wb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//读文件
	fread(&s, sizeof(S), 1, pf);
	printf("%s %d %f", s.name, s.age, s.score);

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

 输出:

 成功打印出来。

4.1 对比一组函数

scanf / fscanf / sscanf

printf / fprintf / sprintf

 

例:

#include <stdio.h>

typedef struct S
{
	char name[20];
	int age;
	float score;
}S;

int main()
{
	S s = { "zhagnsan",120,2.22 };
	char buf[100] = { 0 };
	sprintf(buf, "%s %d %f", s.name, s.age, s.score);
	printf("%s\n", buf);
	S tmp;
	sscanf(buf, "%s %d %f", tmp.name, &(tmp.age), &(tmp.score));
	printf("%s %d %f", tmp.name, tmp.age, tmp.score);
	return 0;
}

输出:

输出:
zhagnsan 120 2.220000
zhagnsan 120 2.220000

5. 文件的随机读写

5.1 fseek

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

5.2 ftell

返回文件指针相对于起始位置的偏移量。(计算文件指针所在位置)

5.3 rewind

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

事先在文件中存储"abcdef"。

例:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
	}
	else
	{
		int ch = fgetc(pf);
		printf("%c\n", ch);
		ch = fgetc(pf);
		printf("%c\n", ch);		
		ch = fgetc(pf);
		printf("%c\n", ch);

		fseek(pf, -2, SEEK_CUR);//文件指针偏移
		ch = fgetc(pf);//查看偏移量
		printf("%c\n", ch);
		rewind(pf);//文件指针返回起始位置

		printf("%d\n", ftell(pf));

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

输出:

输出:
a
b
c
b
0

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

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

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

例:

#include <stdio.h>

int main()
{
	int a = 10000;
	FILE* pf = fopen("test.txt", "wb");
	fwrite(&a, 4, 1, pf);//二进制的形式写到文件中
	fclose(pf);
	pf = NULL;
	return 0;
}

然后再VS中打开这个文件:

然后就能看到:

 

 我们存进内存的数以小端形式存储,

这里展现出的是以十六进制打印出来的结果,其本质就是二进制数。

7. 文件读取结束的判定

7.1 feof

这个函数是用于判断文件读取结束的原因:

如果文件是因为读取失败而结束就返回0,

如果文件是遇到文件尾结束就返回非0数。

8. 文件缓冲区

如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),

然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。

缓冲区的大小根据C编译系统决定的。

例:

 如果缓冲区没满,主动刷新缓冲区也会将数组存入磁盘。

而C语言中调用 fclose 函数就会刷新一下,

所以,写程序如果打开了文件,记得一定要关闭,否则肯数据就丢失了。

写在最后:

以上就是本篇文章的内容了,感谢你的阅读。

如果喜欢本文的话,欢迎点赞和评论,写下你的见解。

如果想和我一起学习编程,不妨点个关注,我们一起学习,一同成长。

之后我还会输出更多高质量内容,欢迎收看。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/164440.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FeignClient调用源码解析

文章目录一、FeignClient二、整体流程1.使用FeignClient2.FeignClient整体调用流程三、源码解析1. 注解EnableFeignClients2. FeignClientsRegistrar3. Feign其他配置4. FactoryBean5. 方法调用一、FeignClient FeignClient作为SrpingCloud进行http请求的一个基础组件&#xf…

IP地址和MAC地址是什么?Dhcp和arp又是什么?

本期武汉海翎光电的小编和大家聊聊 计算机是如何通信的&#xff1f;IP地址和MAC地址是什么&#xff1f;Dhcp和arp又是什么&#xff1f;在我们的家庭网络中&#xff0c;有许多的网络设备&#xff0c;比如我们可以有两台计算机A和B, 一台手机一台电视机&#xff0c;他们都连接到了…

【尚硅谷】Java数据结构与算法笔记09 - 哈希表

文章目录一、哈希表引入二、基本介绍三、Google公司的一个上机题3.1 题目描述3.2 代码实现一、哈希表引入 1&#xff09;看一个实际需求, google 公司的一个上机题: 2&#xff09;有一个公司, 当有新的员工来报道时, 要求将该员工的信息加入(id,性别,年龄, 住址…), 当输入该员…

【Linux】理解文件系统——软硬链接

我们之前讨论的都是进程和被打开文件的关系&#xff0c;而如果一个文件是没有被打开呢&#xff1f;没有被打开的文件操作系统如何管理&#xff1f; 没有被打开的文件在磁盘上&#xff0c;所以磁盘上有大量的文件&#xff0c;这些文件要被静态管理起来&#xff0c;方便我们随时…

1588_AURIX_TC275_PMU简介

全部学习汇总&#xff1a; GreyZhang/g_TC275: happy hacking for TC275! (github.com) PMU是编程存储单元的缩写&#xff0c;但是落实到了具体的硬件模块上其实是一个Flash模块。在TC275中&#xff0c;只有一个PMU模块。在所有的AURIX芯片中&#xff0c;只有PMU0支持BootROM的…

React--》React组件的三大核心属性

目录 state 事件绑定 props 函数式组件使用props refs state state是组件对象最重要的属性&#xff0c;值是对象(可以包含多个 key-value的组合)&#xff1b;组件被称为“状态机”&#xff0c;通过更新组件来对应页面显示(重新渲染组件)&#xff0c;也就是有状态组件&…

ASP.NET Core 3.1系列(29)——System.Text.Json实现JSON的序列化和反序列化

1、前言 在Web开发中&#xff0c;JSON数据可以说是无处不在。由于具有轻量、易读等优点&#xff0c;JSON已经成为当前主流的数据传输格式。在ASP.NET Core 3.0之前&#xff0c;大多数项目都会使用Newtonsoft.Json组件来实现JSON的序列化和反序列化操作&#xff0c;而从ASP.NET…

《王道》操作系统整理

操作系统第1章 OS概述第1节 OS基本概念第2节 OS发展与分类第3节 OS运行机制和体系结构1.3.1 操作系统的运行机制1. 时钟管理2. 中断机制3. 原语4. 系统资源管理或系统控制的数据结构及处理1.3.2 中断和异常1.3.3 系统调用第2章 进程管理第3章 内存管理第4章 文件管理第5章 IO管…

【8】SCI易中期刊推荐——计算机 | 人工智能(中科院4区)

🚀🚀🚀NEW!!!SCI易中期刊推荐栏目来啦 ~ 📚🍀 SCI即《科学引文索引》(Science Citation Index, SCI),是1961年由美国科学信息研究所(Institute for Scientific Information, ISI)创办的文献检索工具,创始人是美国著名情报专家尤金加菲尔德(Eugene Garfield…

【SpringCloud11】Hystrix断路器

Hystrix断路器1.概述1.1分布式系统面临的问题1.2Hystrix 是什么1.3Hystrix 的作用1.4官网资料1.5Hystrix官宣停更进维2.Hystrix重要概念2.1服务降级&#xff08;fallback&#xff09;2.2服务熔断&#xff08;break&#xff09;2.3服务限流&#xff08;flowlimit&#xff09;3.H…

手把手教你使用Python实现推箱子小游戏(附完整源码)

文章目录项目介绍项目规则项目接口文档项目实现过程前置方法编写move核心方法编写项目收尾项目完善项目整体源码项目缺陷分析项目收获与反思项目介绍 我们这个项目是一个基于Python实现的推箱子小游戏&#xff0c;名叫Sokoban&#xff1a; 这个游戏的目的是让玩家&#xff0…

jfow-代码分析

jfow-代码分析目录概述需求&#xff1a;设计思路实现思路分析1.代码&#xff1a;2.代码2&#xff1a;3.CashFrmTemplate4.chartType5.DataColumnData:参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xf…

Vue实战第1章:学习和使用vue-router

学习和使用vue-router 前言 本篇在讲什么 简单讲解关于vue-router的使用 仅介绍简单的应用&#xff0c;仅供参考 本篇适合什么 适合初学Vue的小白 适合想要自己搭建网站的新手 适合没有接触过vue-router的前端程序 本篇需要什么 对Html和css语法有简单认知 对Vue有…

2023/1/14 js基础学习

1 js基础学习-基本数据类型基本语法 请参考 https://blog.csdn.net/m0_48964052?typeblog https://gitee.com/hongjilin/hongs-study-notes/blob/master/%E7%BC%96%E7%A8%8B_%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/HTMLCSSJS%E5%9F%BA%E…

Arthas 入门到实战(二)在线热更新

1. 结合 jad/mc 命令在线修改使用 jad 命令: 将 JVM 中实际运行的 class 的 byte code 反编译成 java 代码&#xff0c;便于你理解业务逻辑&#xff1b; mc命令&#xff1a;Memory Compiler/内存编译器&#xff0c;编译.java文件生成.class。 redefine命令&#xff1a;加载…

unix进程控制及进程环境--自APUE

文章目录概述1、孤儿进程和僵尸进程进程终止进程的编译和启动进程终止的步骤进程8种终止方式进程退出函数1&#xff1a;exit进程退出函数2&#xff1a;_exit进程退出函数3&#xff1a;_Exit注册终止处理程序&#xff1a;atexit环境变量通过main函数传参全局的环境变量表&#x…

uni-app跨端自定义指令实现按钮权限

前言 初看这个标题可能很迷&#xff0c;uni-app明明不支持自定义指令&#xff0c;这文章是在搞笑吗&#xff0c;本文对于uni-app自定义指令实现按钮权限的方式也有可能是多余&#xff0c;但为了给业务部门更友好的开发体验&#xff0c;还是做了一些可能没意义的操作&#xff0…

回顾2022,展望 2023

个人相关&#xff1a; PMP 因为疫情多次延期的PMP终于搞定&#xff0c;光环的PMP就是妥妥。基本只要认真做题和思考都会过。但是考试不仅仅是考试&#xff0c;有时候更多的是对项目发展和项目管理的思考&#xff1a;风险&#xff0c;里程碑&#xff0c;相关方&#xff0c;敏捷&…

红日内网渗透靶场2

目录 环境搭建&#xff1a; Web渗透&#xff1a; weblogic漏洞利用 java反序列化漏洞利用、哥斯拉获取shell 上线msf msf派生shell到cs 内网信息收集 mimikatz获取用户密码 cs横向移动 PTT攻击&#xff08;票据传递&#xff09; 方法2&#xff1a;通过msf利用永恒之蓝…

测试之分类【测试对象、是否查看代码、开发】

文章目录1. 按测试对象分类2. 按照是否查看代码划分3. 按照开发阶段划分1. 按测试对象分类 可靠性测试容错性测试安装卸载测试内存泄露测试弱网测试 &#xff08;1&#xff09;可靠性测试 可靠性 正常运行时间 / (正常运行时间 非正常运行时间) * 100% &#xff08;最高 10…