C语言中文件的读写

news2024/11/26 21:34:41

不争输赢,只问对错

文章目录

一、文件的概述  

二、什么是读写文件

三、文件处理的函数

1.文件的打开与关闭

2.文件的顺序读写

文件的顺序读写相关函数

scanf 和 printf 家族的对比及其区分

3.文件的随机读写      

文件的随机读写函数

四、文件缓冲区

五、文件的读取结束的判定

判断文件是否读取结束的两个标准

被错误使用的feof


  大家好,我是纪宁,作为一个合格的程序员,必须了解文件在程序中创建和使用的机理。本文将介绍C语言中文件相关的内容。

一、文件的概述  

  文件是计算机系统很重要的一部分,经常用于存储文档、图片、表格、书信、视频等各种各样的信息,使用文件我们可以将数据直接存放在电脑的硬盘上,可以做到数据的持久化。那么,学会在程序中读写文件或创建文件是很重要的。 

  在程序设计中,我们一般谈的文件有两种:程序文件、数据文件。程序文件指的是程序本身文件,例如源文件(后缀为.c文件),目标文件(后缀为.obj),可执行文件(windows系统下后缀为.exe);而数据文件指的是程序运行时读写的数据,本文讨论的就是数据文件。

  一个文件要有一个唯一的文件标识,以便用户识别和引用。文件名包含3部分:文件路径+文件名主干+文件后缀例如: c:\code\test.txt 。为了方便起见,文件标识常被称为文件名。

  在C语言中,会将文件看做是一些列的字节,每个字节都能被单独读取。C提供两种文件模式:文本模式和二进制模式

  要区分文本模式和二进制模式,首先要明确一件事,所有文件的内容都以二进制形式(0或1)存储。而如果文件最初使用二进制编码的字符来表示文本,那么该文件就是文本文件,其中包含的是文本内容 ;如果文件中的二进制值代表机器语言或数值数据或一些音乐编码,那么该文件就是二进制文件,其中包含的是二进制内容。

二、什么是读写文件

  读文件就是读取文件,将硬盘中文件内容读取出来使用。 写文件就是将数据写入硬盘的特定文件,方便下次读取。读文件相当于输入,写文件相当于输出。对程序来说,从文件中读数据相当于从键盘输入数据;往文件中写数据相当于在屏幕上输出数据。

三、文件处理的函数

1.文件的打开与关闭

  在C语言中使用 fopen() 函数打开文件,该函数声明在 <stdio,h> 中,第一个参数是一个指针,指向被打开文件的地址,通常也叫文件指针。第二个参数是一个字符串,指定待打开文件的模式。下表为C中提供的一些常用的模式。

模式的字符串含义
"r"以读形式打开文件
"w"以写模式打开文件,并把此文件现有内容全部删除,如果文加不存在,则创建一个文件
"a"以写模式打开文件,在文件末尾添加内容,如果文件不存在,则创建一个文件
"r+"以更新模式打开文件(可以读写文件)
"w+"以更新模式打开文件(即可以读和写),如果文件存在,读取到文件内容后,会将此文件内容全部删除(长度截断为0);如果文件不存在,则创建一个新文件
"a+"以更新模式打开文件(即可以读和写),如果文件存在,在现有文件的末尾添加内容;如果文件不存在,则创建一个新文件;可以读取整个文件,但只能从末尾添加内容

"rb"、"wb"、"ab"、"rb"、"rb+"

"r+b"、"w+b"、"wb+"、"ab+"、"a+b"

字符串中加b之后,功能与上一个类似,但将文件以文本模式打开改为了以二进制模式打开

  程序成功打开文件后,fopen()将返回文件指针(file pointer)该文件指针的类型是指向FILE的指针,FILE 是一个定义在<stdio.h> 中的类型。但pf并不指向实际的文件,它指向一个包含信息文件的数据对象。例如下面读写文件的代码

    FILE* pf = fopen("mhj.txt", "r");//以文本模式读文件
	FILE* pf = fopen("mhj.txt", "w");//以文本模式写文件
	FILE* pf = fopen("mhj.txt", "rb");//以二进制模式读文件
	FILE* pf = fopen("mhj.txt", "wb");//以二进制模式写文件

  fclose(pf) 函数 可以关闭pf指定的文件,必要时会刷新缓冲区。如果关闭成功,fclos()函数返回0,否则返回EOF。关闭后应及时将pf指针置空,防止pf成为野指针。

    fclose(pf);
	pf = NULL;

2.文件的顺序读写

文件的顺序读写相关函数

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

  fgetc 和 fputc 函数与getchar、putcgar函数类似,只不过,后者是从键盘读(输入),写(输出)在屏幕,而前者可以从所有流输入输出。

  举个例子:下面条语句的意思是从标准输入流中获取一个字符:

ch=getchar();

同样的功能,fgetc也可以做到:

ch=fgetc(stdin);

当然,fgetc的主要功能是从文件中读取字符,下面条语句的意思是从pf指定的文件中获取一个字符

ch=fgetc(pf);

  在使用这些文件操作函数时可以模仿标准输入输出流函数的用法,只需要关注它们的参数和要写入的文件指针名即可。

文件输入输出函数

函数返回类型及参数
fgetcint fgetc ( FILE * stream );
fputcint fputc ( int character, FILE * stream );
fgetschar * fgets ( char * str, int num, FILE * stream );
fputsint fputs ( const char * str, FILE * stream );
fscanfint fscanf ( FILE * stream, const char * format, ... );
fprintfint fprintf ( FILE * stream, const char * format, ... );
freadsize_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
fwritesize_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

scanf 和 printf 家族的对比及其区分

  scanf 和 printf 函数只适用于标准输入输出流,即从键盘输入;而fprint函数和fscanf函数使用与所有输入输出流,多几个参数而已。int sprintf ( char * str, const char * format, ... );

  而sscanf和sprintf函数却有着将数据转化为字符串的功能。先观察一下这些函数的参数及返回值

sscanf       int sscanf ( const char * s, const char * format, ...);
sprintf       int sprintf ( char * str, const char * format, ... );

  format是格式的意思,其中一个格式对应一个参数,sscanf sprintf 与标准输入流相同,不过在参数列表中多了一个指针

  char buffer [50];
  int n, a=5, b=3;
  n=sprintf (buffer, "%d plus %d is %d", a, b, a+b);
  printf ("[%s] is a string %d chars long\n",buffer,n);

上面这段代码的意思就是将双引号里面的数据全部转化为字符串并放入buffer中。

3.文件的随机读写      

文件的随机读写函数

fseekint fseek ( FILE * stream, long int offset, int origin );
ftelllong int ftell ( FILE * stream );
rewindvoid rewind ( FILE * stream );

  fseek函数:可以将文件看做数组,在fopen打开的文件中直接定位到任意字节处,根据文件指针的位置和偏移量来定位文件指针。

int main()
{
	FILE* pFile;
	pFile = fopen("example.txt", "wb");
	fputs("This is an apple.", pFile);
	fseek(pFile, 9, SEEK_SET);
	fputs(" sam", pFile);
	fclose(pFile);
	return 0;
}

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

​
#include <stdio.h>
int main()
{
	FILE* pFile;
	long size;
	pFile = fopen("myfile.txt", "rb");
	if (pFile == NULL) perror("Error opening file");
	else
	{
		fseek(pFile, 0, SEEK_END);  
		size = ftell(pFile);
		fclose(pFile);
		printf("Size of myfile.txt: %ld bytes.\n", size);
	}
	return 0;
}

​

rewind函数:让文件指针的位置回到文件的起始位置

#include <stdio.h>
int main()
{
	int n;
	FILE* pFile;
	char buffer[27];
	pFile = fopen("myfile.txt", "w+");
	for (n = 'A'; n <= 'Z'; n++)
		fputc(n, pFile);
	rewind(pFile);
	fread(buffer, 1, 26, pFile);
	fclose(pFile);
	buffer[26] = '\0';
	puts(buffer);
	return 0;
}

  上述代码的意思是先将字符A~Z写入文件 myfile.txt ,再用rewind函数使文件指针回到起始位置,再以二进制的形式读取它们。

四、文件缓冲区

  缓冲区,即临时储存数据的地方,可以提高效率节约时间。且缓冲区这个概念不止在文件里有。在平时输入输出的时候,也会有缓冲区,当用户打错字符的时候,可以直接通过键盘修正,最后按下Enter键,传输的才是正确的输入。下面以文件的缓冲区为例介绍缓冲区是如何提高效率的。

  如果内存从硬盘中拿数据的时候,硬板每输入一个数据,内存就拿一次,每输入一个数据,内存就拿一次......那么内存的内存读取的负担就会非常大,有些数据是源源不断的从硬盘传递过来的,所以就有了缓冲区这个概念。

  缓冲区是系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。计算机从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上;如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等),缓冲区的大小是由C原因的编译器自身决定的。

五、文件的读取结束的判定

判断文件是否读取结束的两个标准

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

  2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。
例如:fread判断返回值是否小于实际要读的个数。

被错误使用的feof

  feof函数的作用是:当文件读取结束的时候,判断是读取结束的原因是否是 遇到文件尾结束。要牢记:在文件读取过程中,不能用feof函数的返回值直接来判断文件的是否结束

在用上述两个方法判断是否结束后,在用feof函数判断读取结束的原因

//判断是什么原因结束的
if (ferror(fp))
	puts("I/O error when reading");
else if (feof(fp))
	puts("End of file reached successfully");

非常感谢各位对纪宁的支持,你们的支持就是我不断更新的动力

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

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

相关文章

【el-tree查询并高亮】vue使用el-tree组件,搜索展开并选中对应节点,高亮搜索的关键字,过滤后高亮关键字,两种方法

第一种&#xff08;直接展开并高亮关键字&#xff09; 效果图这样的&#xff0c;会把所有的有这些关键字的节点都展开 代码&#xff1a; 这里的逻辑就是通过递归循环把所有和关键字匹配的节点筛选出来 然后通过setCheckedKeys方法把他展开选中 然后通过filterReal把关键字高亮…

Hadoop——DataGrip连接MySQL|Hive

1、下载 DataGrip下载&#xff1a;DataGrip: The Cross-Platform IDE for Databases & SQL by JetBrains 2、破解 破解链接&#xff1a;https://www.cnblogs.com/xiaohuhu/p/17218430.html 3、启动环境 启动Hadoop&#xff1a;到Hadoop的sbin目录下右键管理员身份运行…

数学建模学习(2):数学建模各类常用的算法全解析

一、评价类算法 常见的评价算法 1.层次分析法 基本思想 是定性与定量相结合的多准则决策、评价方法。将决策的有关元素分解成 目标层、准则层和方案层 &#xff0c;并通过人们的 判断对决策方案的 优劣进行排序 &#xff0c;在此基础上进行定性和定量分析。它把人的思维过程…

预处理详解

目录 一、预定义符号 二、#define 1.认识#define 2.使用#define 2.1#define定义常量 2.2#define定义宏 2.3#define的替换规则 三、宏定义的其他内容 1.#和## 1.1# 1.2## 2.宏的副作用 3.宏的命名规则 4.undef 5.条件编译 一、预定义符号 #include<stdio.h> int…

通过FPGA实现基于RS232串口的指令发送并控制显示器中目标位置

目录 1.算法理论概述 串口通信模块 指令解析模块 位置控制模块 显示器驱动模块 2.部分核心程序 3.算法运行软件版本 4.算法运行效果图预览 5.算法完整程序工程 1.算法理论概述 通过FPGA实现基于RS232串口的指令发送并控制显示器中目标位置是一种常见的应用场景&#x…

双向不循环链表的认识和基础操作(节点创建,头插头删,尾插尾删,输出和逆置)

头定义&#xff1a; typedef char datatype[20];//datatypechar[20] typedef struct Node {//数据域 数据元素datatype data;//指针域 下一个节点地址struct Node* next;//指针域 上一个节点地址struct Node* prev; }*DoubleLink; 创建节点&#xff1a; DoubleLink create_n…

校园电气安全风险分析及预防措施 安科瑞 许敏

摘要:校园属于人员密集场所&#xff0c;若安全风险排查、管控不到位&#xff0c;可能导致安全事故发生&#xff0c;造成严重事故后果。校园电气设备设施引起的电气火灾和触电等事故&#xff0c;是构成校园安全威胁之一&#xff0c;笔者通过对校园发生的电气安全事故案例原因分析…

一次线上OOM问题的个人复盘

我们一个java服务上线后&#xff0c;偶尔会发生内存OOM(Out Of Memory)问题&#xff0c;但由于OOM导致服务不响应请求&#xff0c;健康检查多次不通过&#xff0c;最后部署平台kill了java进程&#xff0c;这导致定位这次OOM问题也变得困难起来。 最终&#xff0c;在多次review代…

react目录结构

比较全面的react目录结构。 目录详解 assets&#xff1a;放置原始资源文件。 components&#xff1a;存放全局组件。 contants&#xff1a;常量文件夹&#xff0c;存放常量。 i18n&#xff1a;i18n国际化&#xff0c;各种语言的翻译。 pages&#xff1a;页面文件夹。 r…

es添加索引命令行和浏览器添加索引--图文详解

一、添加索引 创建索引 curl -X PUT "localhost:9200/my-index-00001?pretty" 获取索引 curl -X GET "localhost:9200/my-index-000001?pretty" 获取全部的索引 curl -X GET "http://localhost:9200/_cat/indices?v" 获取索引映射 cur…

2023 Pycharm 给项目配置解释器 基于已经创建的conda虚拟环境

我在2019年开始使用Pycharm作为python的IDE&#xff0c;最近配置解释器时&#xff0c;法线网上的方法大概过时了&#xff0c;自己尝试了好多次才发现新版本的Pycharm的解释配置方法&#xff0c;故记于此 背景描述&#xff1a; 我是用conda管理环境的&#xff0c;我已经创建好一…

C++ 单例模式(介绍+实现)

文章目录 一. 设计模式二. 单例模式三. 饿汉模式四. 懒汉模式结束语 一. 设计模式 单例模式是一种设计模式 设计模式(Design Pattern)是一套被反复使用&#xff0c;多数人知晓的&#xff0c;经过分类的&#xff0c;代码设计经验的总结。 为什么要有设计模式 就像人类历史发展会…

Docker容器网络和资源管理控制

Docker容器网络 一、Docker 网络实现原理二、Docker 的网络模式网络模式详解&#xff1a;①host模式②container模式③none模式④bridge模式⑤自定义网络 三、资源控制Ⅰ、CPU资源控制Ⅱ、对内存使用的限制Ⅲ、对磁盘IO配额控制&#xff08;blkio&#xff09;的限制 一、Docker…

前端vue uni-app仿美团下拉框下拉筛选组件

在前端Web开发中&#xff0c;下拉筛选功能是一种非常常见的交互方式&#xff0c;它可以帮助用户快速选择所需的选项。本文将介绍如何利用Vue.js和uni-app框架来实现一个高效的下拉筛选功能。通过使用这两个强大的前端框架&#xff0c;我们可以轻松地创建具有响应式用户操作的下…

Hbuildx下载内置浏览器失败

问题描述 刚开始接触Hbulidx&#xff0c;在下载内置浏览器时&#xff0c;报错 " Hbulidx内置浏览器下载失败 " 原因分析 从网上搜索相关的解决方法&#xff0c;一般都是说检查网络&#xff0c;或者关闭杀毒软件。这并没有解决问题&#xff0c;所以&#xff0c;我就…

【C++】STL之容器适配器——使用deque适配stack和queue

个人主页&#xff1a;&#x1f35d;在肯德基吃麻辣烫 分享一句喜欢的话&#xff1a;热烈的火焰&#xff0c;冰封在最沉默的火山深处。 文章目录 前言一、什么是容器适配器&#xff1f;二、stack的基本函数和模拟实现三、queue的基本函数和模拟实现 四、deque4.1deque的底层结构…

如何解决 Git 合并冲突

在遇到合并冲突时&#xff0c;请不要惊慌。通过一些娴熟的技巧协商&#xff0c;你可以解决任何冲突。 假设你和我正在共同编辑同一个名称为 index.html 的文件。我对文件进行了修改&#xff0c;进行了提交&#xff0c;并将更改推送到 Git 远程仓库。你也对同一个文件进行了修改…

K8S初级入门系列之六-控制器(RC/RS/Deployment)

一、前言 在第一章我们了解到&#xff0c;如果master节点是一个大脑&#xff0c;那么控制器组件就是大脑的总管&#xff0c;用来控制Pod的状态和行为。今天我们就来认识弹性扩缩容相关的控制器ReplicationController&#xff0c;ReplicaSet&#xff0c;Deployment。 二、Repli…

(汽车MCU)FS32K148UJT0VLLT、FS32K148HAT0MLLT、FS32K148UJT0VLUT基于32位Cortex-M4F内核 架构图

S32K 32位汽车通用微控制器 (MCU) 是一系列符合AEC-Q100标准、基于32位ARM Cortex-M4F内核的可扩展MCU&#xff0c;适用于通用汽车和高可靠性工业应用。这些系列提供具有可扩展性的软硬件兼容系列&#xff0c;有多种性能、存储器和特性可供选择。这些MCU提供ISO、CAN FD、CSEc硬…

如何使用curl下载github代码

首先通过chrome打开想要下载的源文件 如图&#xff0c;有那个下载图标时表示不需要鉴权即可下载&#xff0c;一般仓库都会开放只读权限&#xff0c;所以很大概率都有 比如我想下载这个crc32.c文件 那么我就需要知道它在哪个IP中&#xff0c;按下F12打开网络&#xff0c;点击下载…