【C语言】文件操作揭秘:C语言中文件的顺序读写、随机读写、判断文件结束和文件缓冲区详细解析【图文详解】

欢迎来CILMY23的博客喔,本篇为【C语言】文件操作揭秘:C语言中文件的顺序读写、随机读写、判断文件结束和文件缓冲区详细解析【图文详解】,感谢观看,支持的可以给个一键三连,点赞关注+收藏。

前言 

欢迎来到本篇博客,上一篇我们详细介绍C语言中的文件操作。

在计算机领域,文件是一种常见的存储和处理信息的方式。通过文件,我们可以将数据和程序永久保存在硬盘中,并随时读取和修改。本篇博客将深入探讨文件操作、文件的顺序读写、随机读写、判断文件结束和文件缓冲区详细解析。

上一篇博客链接:

【C语言】文件操作篇-----程序文件和数据文件,文件的打开和关闭,二进制文件和文本文件,fopen,fclose【图文详解】-CSDN博客

文章目录

一、文件的顺序读写

1.1 文件顺序读写的函数介绍:

 1.2 fgetc和fputc的使用

1.3 fgets和fputs的使用

1.4 fprintf和printf的使用 

1.5 fscanf和scanf的使用 

1.6 sscanf和sprintf的介绍和使用 

1.7 fwrite和fread的使用 

1.8 总结

二、文件的随机读写

2.1 fseek函数 

 2.2 ftell函数

三、文件读取结束的判定

四、文件缓冲区 


一、文件的顺序读写

文件顺序读写是指按照数据在文件中的顺序依次读取或写入数据的操作方式。在文件顺序读写中,数据按照其存储在文件中的顺序被逐个读取或写入。

对于顺序读取,程序会依次读取文件中的数据,从文件的开头一直读取到末尾,直到到达文件结束的位置或者读取到所需的数据为止。每次读取数据后,读取指针会自动向后移动到下一个数据的位置。

对于顺序写入,程序会依次将数据写入文件,从文件的结尾开始写入,每写入一个数据后,写入指针会自动移动到下一个位置,以便写入下一个数据。这样,数据会按照写入的顺序依次添加到文件中。

1.1 文件顺序读写的函数介绍:

 上面说的使用于所有输入流⼀般指使用于标准输入流和其他输入流(如文件输入流);所有输出流⼀般指使用于标准输出流和其他输出流(如文件输出流)。

fgetc 和 fputc: 这两个函数用于逐个字符地读取和写入文件。(一次读取(写入)一个)

它们的原型如下:

int fgetc(FILE *stream);
int fputc(int character, FILE *stream);

fgets:从指定文件中读取一行数据(包括换行符),并将其存储到指定的字符数组中。

原型如下:

char *fgets(char *str, int n, FILE *stream);

fputs:将指定的字符串写入到指定文件中。(一次写一行数据)

原型如下:

int fputs(const char *str, FILE *stream);

fscanf: 该函数用于从文件中按照指定的格式读取数据。

它的原型如下:

int fscanf(FILE *stream, const char *format, ...);

fprintf: 该函数用于向文件中按照指定的格式写入数据。

它的原型如下:

int fprintf(FILE *stream, const char *format, ...);

fread函数:

  • 函数原型:
    size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
  • 功能:从指定文件中读取二进制数据,并将其存储到指定的内存位置。
  • 参数:
    • ptr:指向存储读取的数据的内存位置的指针。
    • size:每个数据项的字节数。
    • count:要读取的数据项的个数。
    • stream:指向已打开文件的指针,表示从该文件中读取数据。
  • 返回值:返回实际成功读取的数据项数目,如果返回值少于count,则可能表示已到达文件末尾或发生了错误。

fwrite函数:

  • 函数原型:
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
  • 功能:将二进制数据写入指定文件中。
  • 参数:
    • ptr:指向要写入的数据的内存位置的指针。
    • size:每个数据项的字节数。
    • count:要写入的数据项的个数。
    • stream:指向已打开文件的指针,表示将数据写入到该文件中。
  • 返回值:返回实际成功写入的数据项数目,如果返回值少于count,则可能表示发生了错误。

 1.2 fgetc和fputc的使用

我们现在在当前路径下:C:\Users\云山若汐\source\repos\test2\test2

放入两个文件, 

write可以不放,然后我们在text中输入abcd,我们现在将要拷贝当中的字符到write中,所以写下以下代码:

#include<stdio.h>int main()
{char ch;FILE* pfread = fopen("text.txt", "r");if (pfread == NULL){perror("fopen - 1");return 1;}FILE* pfwrite = fopen("write.txt", "w");if (pfwrite == NULL){perror("fopen - 2");return 1;}while ((ch = fgetc(pfread)) != EOF){fputc(ch, pfwrite);}fclose(pfread);pfread = NULL;fclose(pfwrite);pfwrite = NULL;
}

效果如下: 

1.3 fgets和fputs的使用

假设此时text中有两行,它们分别是:

 

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

我们使用fgets从文件中获取信息,注意fgets只会从指定文件中读取一行数据(包括换行符)也就是换行符是固定的,我们读取20只会读取前十九个字符因为最后一个字符要存放换行符。

1.4 fprintf和printf的使用 

 假设我们定义了一个结构体如下所示,那我们可以使用printf将其打印到屏幕上,也可以使用fprintf将其打印至屏幕上,或者将其写入文件中

struct S
{int n;float f;char arr[100];
};int main()
{struct S s = { 100,3.14f,"zhangsan" };FILE* pf = fopen("text.txt", "w");if (pf == NULL){perror("fopen");return 1;}//输出到屏幕上printf("%d %f %s\n", s.n, s.f, s.arr);fprintf(stdout, "%d %f %s", s.n, s.f, s.arr);//使用fprintf输出到文件中fprintf(pf, "%d %f %s\n", s.n, s.f, s.arr);fclose(pf);pf = NULL;return 0;
}

效果如下:

1.5 fscanf和scanf的使用 

struct S
{int n;float f;char arr[100];
};int main()
{struct S s = {0};FILE* pf = fopen("text.txt", "r");if (pf == NULL){perror("fopen");return 1;}fscanf(pf,"%d %f %s",&(s.n), &(s.f), &(s.arr));printf("%d %f %s", s.n, s.f, s.arr);fclose(pf);pf = NULL;return 0;
}

 我们用"fopen"打开一个名为"text.txt"的文件来读取数据。如果打开成功,你使用"fscanf"函数从文件中读取整数、浮点数和字符串,存储到结构体"s"的相应成员中。注意,在"%s"格式符后,使用"s.arr"而不是"&"操作符(因为数组名本身就是数组的首地址)

1.6 sscanf和sprintf的介绍和使用 

在本文中,我们将介绍C++中两个常用的输入输出解析函数:sscanf和sprintf。这两个函数提供了灵活的方式来处理字符串和变量之间的格式化输入输出操作。

  • sscanf函数:
    • sscanf函数用于将字符串按照指定的格式解析,并将解析后的值存储到对应的变量中。
    • 语法:int sscanf(const char* str, const char* format, ...)
    • str为输入的字符串,format为格式化字符串,...为对应的变量列表。
#include <stdio.h>int main() {const char* str = "23.5 10";float f;int i;sscanf(str, "%f %d", &f, &i);printf("解析出的浮点数为:%.2f\n", f);printf("解析出的整数为:%d\n", i);return 0;
}
  • sprintf函数:
    • sprintf函数用于将格式化的数据输出到字符串中。
    • 语法:int sprintf(char* str, const char* format, ...)
    • str为输出的字符串,format为格式化字符串,...为对应的变量列表。
#include <stdio.h>int main() {char str[100];int i = 42;float f = 3.14;sprintf(str, "整数:%d,浮点数:%.2f", i, f);printf("格式化后的字符串:%s\n", str);return 0;
}

sscanf和sprintf函数是C语言中常用的输入输出解析函数,可以方便地进行字符串的解析和格式化输出

1.7 fwrite和fread的使用 

 fwrite的使用

#include <stdio.h>int main()
{int arr[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };FILE* pf = fopen("text.txt", "wb");if (pf == NULL){perror("fopen");return 1;}fwrite(arr, sizeof(int), 10, pf); // 写入整个数组fclose(pf);pf = NULL;return 0;
}

我们可以在项目中用二进制形式查看这个txt文件 ,右键该文件,选择打开方式,选择底部的二进制编辑器,

 ​​​​​

 我们可以看到文件中写入了几个数

那如何验证我们是否写入了呢?这时候我们就需要用到fread

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

1.8 总结

二、文件的随机读写

C语言中的随机读写通常指的是以随机的方式访问文件中的数据,而不是按顺序逐个读取或写入。这种随机的读写通常涉及到文件指针的定位,可以根据需要在文件中的不同位置进行读写操作。

 C语言提供了两个函数来进行文件的随机读写,它们分别是fseek和ftell

2.1 fseek函数 

fseek - C++ Reference (cplusplus.com)

  • fseek 函数:

    • 函数原型:
    • int fseek ( FILE * stream, long int offset, int origin );
    • 功能:移动文件流中的读写位置,进行随机的文件定位。
    • 参数:
      • stream:指向文件的指针。
      • offset:偏移量,用于指定文件指针要移动的位置。
      • origin:指定起始位置,可以取三个值:
      • SEEK_SET :文件的开始位置
      • SEEK_CUR:文件指针的当前位置
      • SEEK_END:文件的末尾位置
    • 返回值:如果成功,返回0;否则,返回非0值(通常是-1)。

fseek的使用,fseek函数主要有三种origin的起始值 

 至于偏移量就是距离我的origin有多远了,从1字节开始算

例如:

假设我的text里存了CILMY23

#include <stdio.h>int main()
{FILE* pf = fopen("text.txt", "r");if (pf == NULL){perror("fopen");return 1;}fseek(pf, 0, SEEK_SET);//Cchar ch = fgetc(pf);printf("%c\n", ch);fseek(pf, -1, SEEK_END);//3ch = fgetc(pf);printf("%c\n", ch);fseek(pf, -5, SEEK_CUR);//Lch = fgetc(pf);printf("%c\n", ch);fclose(pf);pf = NULL;return 0;
}

 2.2 ftell函数

 ftell - C++ Reference (cplusplus.com)

 ftell函数:

  • 原型:
    long int ftell ( FILE * stream );
  • 功能:获取当前文件位置指针的偏移字节数。
  • 参数:
    • stream:指向文件的指针。
  • 返回值:返回当前文件位置指针的偏移字节数。

例如: 

#include <stdio.h>int main()
{FILE* pf = fopen("text.txt", "r");if (pf == NULL){perror("fopen");return 1;}fseek(pf, -1, SEEK_END);//3char ch = fgetc(pf);printf("%c\n", ch);int ret = ftell(pf);printf("%d", ret);fclose(pf);pf = NULL;return 0;
}

三、文件读取结束的判定

文件读取结束可以通过feof函数进行判定。feof函数用于检测文件流上的结束标志。当文件末尾已经读取,feof函数返回非零值;否则返回0。

文件读取结束的原因可能有:

1.文件遇到末尾

2.文件发生错误

#include<stdio.h>int main()
{FILE* pf = fopen("text.txt", "r");if (pf == NULL){perror("fopen");return 1;}int ch;while ((ch = fgetc(pf)) != EOF){// 处理读取的字符if (feof(pf)){printf("文件读取结束\n");}else{printf("文件读取出错\n");}}fclose(pf);pf = NULL;return 0;
}

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

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

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

四、文件缓冲区 

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

因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。如果不做,可能导致读写文件的问题。 

通过本篇博客,相信你了解了C语言中文件操作的核心内容。文件的顺序读写、随机读写、文件读取结束的判定以及文件缓冲区等知识点,感谢你的阅读!如果你对文件操作还有任何疑问或需要进一步的帮助,请随时留言,如果你觉得还不错的话,可以给个一键三连,点赞关注加收藏,本篇博客就到此结束了。

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

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

相关文章

Java AOP 简单实例演示

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

WT32-ETH02 plus 串口转以太网开发,WT32-ETH01网关开发板升级款!

广受欢迎的WT32-ETH01网关开发板迎来了升级。 就是这款启明云端新推出的嵌入式串口转以太网开发板——WT32-ETH02 plus。应广大客户的需求&#xff0c;在WT32-ETH01的基础上增加了POE供电&#xff0c;可广泛应用于智能家居和网关等应用。开发板搭载2.4GHz Wi-Fi和蓝牙双模的SO…

一键部署灵境矩阵,属于自己的ai智能平台。

灵境矩阵 | 想象即现实 “灵境杯”智能体创意大赛&#xff0c;瓜分百万超级奖励 打造专属AI智能平台&#xff1a;一键部署灵境矩阵的无限可能 在数字化浪潮席卷全球的今天&#xff0c;人工智能技术已逐渐成为推动社会进步的关键力量。面对这一趋势&#xff0c;许多企业和个人…

永续合约多空双开“戴套”策略的逻辑是什么,胜率惊人的96%是怎么做到的,其实并没有想的那么复杂,会代码的都可以写出来

为什么叫多空双开“戴套”量化策略呢&#xff0c;因为这个策略的特点是永远有一个仓位是被套的&#xff0c;但是这个不影响我们盈利&#xff0c;具体怎么实现大家看下面这个图就明白是怎么回事了。 这个策略的逻辑很简单也容易理解&#xff0c;就是多空双开&#xff0c;盈利平仓…

FREERTOS空闲任务和低功耗

空闲任务 空闲任务是 FreeRTOS 必不可少的一个任务&#xff0c;其他 RTOS 类系统也有空闲任务&#xff0c;比如uC/OS。看名字就知道&#xff0c;空闲任务是处理器空闲的时候去运行的一个任务&#xff0c;当系统中没有其他就绪任务的时候空闲任务就会开始运行&#xff0c;空闲任…

slab分配器

什么是slab分配器&#xff1f; 用户态程序可以使用malloc及其在C标准库中的相关函数申请内存&#xff1b;内核也需要经常分配内存&#xff0c;但无法使用标准库函数&#xff1b;linux内核中&#xff0c;伙伴分配器是一种页分配器&#xff0c;是以页为单位的&#xff0c;但这个…

基于 Echarts + Python Flask ,我搭建了一个动态实时大屏监管系统

一、效果展示 1. 动态实时更新数据效果图 2. 鼠标右键切换主题 二、确定需求方案 支持Windows、Linux、Mac等各种主流操作系统&#xff1b;支持主流浏览器Chrome&#xff0c;Microsoft Edge&#xff0c;360等&#xff1b;服务器采用python语言编写&#xff0c;配置好python环…

计算机设计大赛 题目: 基于深度学习的疲劳驾驶检测 深度学习

文章目录 0 前言1 课题背景2 实现目标3 当前市面上疲劳驾驶检测的方法4 相关数据集5 基于头部姿态的驾驶疲劳检测5.1 如何确定疲劳状态5.2 算法步骤5.3 打瞌睡判断 6 基于CNN与SVM的疲劳检测方法6.1 网络结构6.2 疲劳图像分类训练6.3 训练结果 7 最后 0 前言 &#x1f525; 优…

Orange3数据预处理(公式组件)

公式 为您的数据集添加新特征。 输入 数据&#xff1a;输入数据集 输出 数据&#xff1a;带有额外特征的数据集 公式组件允许通过使用用户定义的表达式来计算新列。结果列可以是分类的、数值的或文本的。 对于数值变量&#xff0c;只需提供名称和表达式。 1.构建变量列表…

学点儿Java_Day7_在实体类当中IDEA无法进行单元测试(@Test没有启动按钮)

在敲代码体会继承和访问修饰符的时候忽然遇到了单元测试不管用的情况&#xff0c;表现为没有启动按钮   经过一番折腾&#xff0c;发现我的测试是在具有构造函数的实体类Person当中进行的&#xff0c;当我把所有的构造函数删除后&#xff0c;启动按钮又出来了&#xff0c;加…

水电能源智能化监控系统

水电能源智能化监控系统是利用现代信息技术&#xff0c;对水电站的运行状态、设备性能、环境参数等进行实时监测和管理的一种智能化系统。随着我国水电能源事业的快速发展&#xff0c;水电能源智能化监控系统在水电能源行业中的应用越来越广泛&#xff0c;为我国水电能源事业的…

关于继承是怎么样的?那当然是很好理解之

本文描述了关于继承的大部分知识&#xff0c;但是并不全&#xff0c;每篇博客之间的知识都有互串&#xff0c;所以需要把几篇文章合起来看&#xff0c;学会融会贯通&#xff01; 温馨提示&#xff1a;使用PC端观看&#xff0c;效果更佳&#xff01; 目录 1.继承是什么 2.什…

【位运算】【 数学】【 哈希映射】2857. 统计距离为 k 的点对

本文涉及知识点 位运算 数学 哈希映射 LeetCode 2857. 统计距离为 k 的点对 给你一个 二维 整数数组 coordinates 和一个整数 k &#xff0c;其中 coordinates[i] [xi, yi] 是第 i 个点在二维平面里的坐标。 我们定义两个点 (x1, y1) 和 (x2, y2) 的 距离 为 (x1 XOR x2) …

STM32最小核心板使用HAL库实现UART接口通讯(中断方式)

正式环境里需要串联电阻&#xff0c;或设计过滤电路。核心板是STM32F103C8T6 这里使用了UART3的接口&#xff0c;具体使用MX创建项目就不放了&#xff0c;百度下都有 /*USART3 GPIO ConfigurationPB10 ------> USART3_TXPB11 ------> USART3_RX */ 因为是串口…

开发技术-FeignClient 对单个接口设置超时时间

1. 背景 FeignClient 调用某个接口&#xff0c;3s 没有结果就需要停止&#xff0c;处理后续业务。 2. 方法 FeignClient 自定义 name 属性 FeignClient(name "aaa" , url "xxx") public interface TestApi {ResponseBodyPOSTMapping(value "xx…

以码会友|PR大征集!2024共绘 MoonBit 新篇章!

首先&#xff0c;感谢 MoonBit 社区所有的贡献者在过去一个月积极的参与和贡献&#xff01;为了感谢与鼓励更多的MoonBit Contributor&#xff0c;我们以码会友&#xff0c;邀请你加入“一起成为MoonBit Contributor&#xff01;” 的活动&#xff01; 活动内容也可以点击文章…

【第十三章】改进神经网络学习方式-其他正则化技术

L1正则化 除了L2正则化之外&#xff0c;还有许多正则化技术。事实上&#xff0c;已经开发出了如此多的技术&#xff0c;以至于我不可能总结它们。在本节中&#xff0c;我简要介绍了三种减少过拟合的其他方法&#xff1a;L1正则化、dropout和人为增加训练集大小。我们不会像之前…

在ComfyUI中,IP-Adapter的一大堆模型应该怎么放?

&#x1f381;背景介绍 IP-Adapter有一大堆的模型&#xff0c;那么这个模型在ComfyUI中&#xff0c;这些模型到底应该怎么放呢&#xff1f;这篇文章简单介绍一下。 首先&#xff0c;大家需要到huggingface上找到对应的模型&#xff0c;把所有的模型先下载下来。 huggingface…

技术工作报告-基于linux的信息转二维码图像方法的研究

一、摘要&#xff1a; 本报告旨在介绍基于Linux的信息转二维码图像方法的研究。通过对二维码技术的背景和相关研究的调研&#xff0c;我们提出了一种基于Linux平台的信息转二维码图像方法&#xff0c;并进行了实验验证。本方法可以在Linux系统上实现高效、准确的信息转二维码图…

数据分析的具体流程

1.导入 表格导入数据时要注意数据的格式问题非表格导入 可以先将文档放入word中 将换行符&#xff08;^p&#xff09;替换为|||&#xff0c;选择特殊格式中的段落标记 进行全部替换 以每一列最后的数据/平&#xff0c;作为换行的标志 将所整理的信息导入excel,对数据进行分列 选…