C语言-常见文件操作函数详解(fgetc,fputc,fgets,fputs,fscanf,fprintf,fread,fwrite)

在这里插入图片描述

 🌏个人博客:尹蓝锐的博客

在这里插入图片描述

希望文章能够给到初学的你一些启发~ 如果觉得文章对你有帮助的话,点赞 + 关注+ 收藏支持一下笔者吧~

顺序读写数据常用函数

函数名调用形式功能返回值
fgetcfgetc(fp)从指针变量fp指向的文件中读入一个字符读成功,返回所读字符,失败返回EOF(即-1)
fputcfputc(fp)把字符ch写到文件指针变量fp所指向的文件中输出成功返回值就是输出的字符,输出失败返回EOF(即-1)
fgetsfgets(str,n,fp)

从fp指向的文件读入一个长度为(n-1)的字符串,存放到字符数组str中

tips:读n-1个是因为fgets函数要固定留一个字符 '\0' 作为字符串结束标志

读成功,返回地址str,失败则返回NULL
fputsfputs(str,fp)

把str所指向的字符串写到文件指针变量fp所指向的文件中

输出成功,返回0;否则返回非0值
fscanffscanf(fp,"%d",i)将int类型变量i的值按照%d的格式输出到fp指向的文件中成功后,将返回写入的字符总数。否则并返回负数。
fprintffprintf(fp,"%f",j)将float类型的变量j的值按照%f的格式输出到屏幕上成功后,将返回写入的字符总数。否则并返回负数。

fread

fread(buffer,size,count,fp)从fp中读取一个含有count个元素的数组,每个元素的大小为size个字节,并将其存储在buffer指定的内存块中。返回成功读取的元素总数
fwritefwrite(buffer,size,count,fp)从buffer指向的内存块向文件流中写入一个包含count个元素数组,每个元素的大小为size个字节。流的位置指示器按写入的总字节数前进。返回成功写入的元素总数。

1、fgetc

int fgetc ( FILE * stream );

  1. 从流中获取字符
  2. 返回指定流的内部文件位置指示符当前指向的字符。然后,内部文件位置指示器将前进到下一个字符。
  3. 如果调用时流位于文件末尾,则函数返回EOF并为流设置文件末尾指示符(feof)。
  4. 如果发生读取错误,该函数将返回EOF并为流设置错误指示符(ferror)。
  5. fgetc和getc是等效的,除了getc可以在某些库中实现为宏。

为了更加具体理解,我们创建一个文件并输入一些字符

 在保证文件有内容可读取后,我们以只读的方式打开文件,使用ch变量挨个读取文件中的字符

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{FILE *fp = fopen("test.txt", "r");if (fp == NULL){perror("fopen");return 1;}char ch = getc(fp);printf("%c", ch);ch = getc(fp);printf("%c", ch);fclose(fp);fp = NULL;return 0;
}

运行结果如下:

2、fputc

int fputc ( int character, FILE * stream );

  1. 向流写入字符将字符写入流并推进位置指示器。
  2. 字符被写在流的内部位置指示器指示的位置,然后自动前进一个。

使用fputc向文件中挨个写入字符

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{FILE *fp = fopen("test.txt", "w");//只写方式打开if (fp == NULL){perror("fopen");return 1;}char ch[10] = "excellent!";for (int i = 0; i < 10; i++){fputc(ch[i], fp);}fclose(fp);fp = NULL;return 0;
}

运行结果如下,test被成功写入字符

这里需要注意的是:如果test.txt文件中本来有内容,原来的内容会被清空

3、fgets

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

  1. 从流中获取字符串
  2. 从流中读取字符,并将其作为字符串存储到str中,直到读取了(num-1)个字符,或者到达换行符或文件末尾,以先发生者为准。
  3. 换行符会使fgets停止读取,但函数会将其视为有效字符,并将其包含在复制到str的字符串中。
  4. 在复制到str的字符之后,会自动附加一个终止空字符。
  5. 请注意,fgets与gets有很大不同:fgets不仅接受流参数,还允许指定str的最大大小,并在字符串中包含任何换行符。

确保test.txt文件有内容的情况下,用只读方式打开文件

通过fgets函数获取文件中的字符串并将其保存至字符数组ch中,代码如下

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{FILE *fp = fopen("test.txt", "r");//只读方式打开if (fp == NULL){perror("fopen");return 1;}char ch[10];fgets(ch, sizeof(ch), fp);puts(ch);fclose(fp);fp = NULL;return 0;
}

运行结果如下

我们需要注意的是本代码调用fgets函数时,第二个参数使用sizeof(ch),计算字符数组ch所占字节数,计算结果值为10,而fgets函数第二个参数代表取10-1个,即9个字符,所以文件中只有9个字符被存入字符数组ch中,原本文件内容excellent后的  !没有被输出

4、fputs

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

  1. 将字符串写入流
  2. 将str指向的字符串写入流。
  3. 函数从指定的地址(str)开始复制,直到到达终止的空字符(“\0”)。此终止空字符不会复制到流中。
  4. 请注意,fputs与put的不同之处不仅在于可以指定目标流,而且fputs不会写入额外的字符,而put会自动在末尾添加换行符。

通过fputs函数向文件中写入字符串

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{FILE *fp = fopen("test.txt", "w");//只写方式打开if (fp == NULL){perror("fopen");return 1;}char ch[11]="wonderful!";fputs(ch,fp);fclose(fp);fp = NULL;return 0;
}

运行结果如下:

5、fscanf

int fscanf ( FILE * stream, const char * format, ... );
  1. 从流中读取格式化数据
  2. 从流中读取数据,并根据参数格式将其存储到附加参数指向的位置。
  3. 附加参数应指向格式字符串中由其相应格式说明符指定的类型的已分配对象。

首先保证test.txt文件中有内容

使用scanf用格式化的方式读取文件中的内容,代码如下

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{FILE *fp = fopen("test.txt", "r");//只写方式打开if (fp == NULL){perror("fopen");return 1;}int n;fscanf(fp, "%d", &n);printf("%d", n);fclose(fp);fp = NULL;return 0;
}

运行结果如下

6、fprintf

int fprintf ( FILE * stream, const char * format, ... );
  1. 将格式化数据写入流
  2. 将按格式指向的字符串写入流。如果format包含格式说明符(以%开头的子序列),则格式化format之后的其他参数并将其插入到结果字符串中,替换其各自的说明符。
  3. 在format参数之后,函数需要至少与format指定的额外参数一样多的参数。

使用fprintf函数向文件中格式化输出内容

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{FILE *fp = fopen("test.txt", "w");//只写方式打开if (fp == NULL){perror("fopen");return 1;}int n = 123456;fprintf(fp, "%d", n);fclose(fp);fp = NULL;return 0;
}

运行结果如下:

7、fread

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
  1. 从流中读取数据块
  2. 从流中读取一个count个元素组成的数组,每个元素的大小为size个字节,并将其存储在ptr指定的内存块中。
  3. 流的位置指示器按读取的总字节数前进。
  4. 如果成功,读取的字节总数为(size(大小)*count(计数))。

该函数一共有4个参数:

  1. ptr指向大小至少为(大小*计数)字节的内存块的指针,转换为void*。
  2. size要读取的每个元素的大小(以字节为单位)。
  3. size_t是一个无符号整数类型。
  4. count元素的数量,每个元素的大小为字节。
  5. size_t是一个无符号整数类型。
  6. stream指向指定输入流的FILE对象的指针。

首先保证test.dat该二进制文件中有数据,我这里给的是123456,可将test.txt中输入数据后修改文件名成.dat

使用fread函数从二进制文件中读入数据存入字符数组arr中,并输出

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{FILE *fp = fopen("test.dat", "rb");//只读方式打开,且读的是二进制文件if (fp == NULL){perror("fopen");return 1;}char arr[7] = { 0 };fread(arr, sizeof(arr[0]), sizeof(arr), fp);printf("%s", arr);// arr : 将文件读取到内存的位置// sizeof(arr[0]) : 读取的元素字节大小// sizeof(arr) : 读取元素的个数,// 读取字节个数是 sizeof(arr) * sizeof(arr[0])// fp : 文件指针fclose(fp);fp = NULL;return 0;
}

运行结果如下:

8、fwirte

size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
  1. 将数据块写入流
  2. 从ptr指向的内存块向流中的当前位置写入含有count个元素的数组,每个元素的大小为size字节
  3. 流的位置指示器按写入的总字节数前进。
  4. 在内部,该函数将ptr指向的块解释为一个无符号char类型的(大小*计数)元素数组,并将它们顺序写入流,就像每个字节都调用了fputc一样。

本函数由4个参数(与fread类似)

  1. ptr指向要写入的元素数组的指针,转换为const void*。
  2. size要写入的每个元素的大小(以字节为单位)。
  3. size_t是一个无符号整数类型。
  4. count元素的数量,每个元素的大小为字节。
  5. size_t是一个无符号整数类型。
  6. stream指向指定输出流的FILE对象的指针。

我们使用fwirte函数向二进制文件test.dat写入字符串hello,操作如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{FILE *fp = fopen("test.dat", "wb");//只写方式打开,且写的是二进制文件if (fp == NULL){perror("fopen");return 1;}char arr[7] = { "hello" };fwrite(arr, sizeof(arr[0]), sizeof(arr), fp);// arr : 将文件读取到内存的位置// sizeof(arr[0]) : 读取的元素字节大小// sizeof(arr) : 读取元素的个数,// 读取字节个数是 sizeof(arr) * sizeof(arr[0])// fp : 文件指针fclose(fp);fp = NULL;return 0;
}

检验:将test.dat后缀改成txt文件,打开发现更改成功

  如果我的博客能给您带来启发,请不吝点赞、评论和收藏,也欢迎您关注我的博客。

  如果你喜欢这篇文章,别忘了留下你的感想和建议,让我知道你的想法。同时,也请继续关注我的博客,我们不见不散!

  最后,愿每一位读到这里的你,都能拥有一个充实而美好的每一天。不管世界怎样变化,保持学习,保持热爱,保持对生活的好奇心,我们的故事,还在继续……

在这里插入图片描述

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

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

相关文章

Spring Boot 进阶-详解Spring Boot整合数据库

在之前的例子中&#xff0c;我们介绍了如何在Spring Boot 框架中添加数据源配置。这篇文章我们来详细介绍一下如何整合Mybatis框架。 整合Mybatis框架 还是按照之前的套路&#xff0c;我们要整合Mybatis框架&#xff0c;首先需要加载对应的场景启动器。这里我们引入由Mybatis提…

【AI 工具分享】

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

刷题 图论

面试经典 150 题 - 图 200. 岛屿数量 dfs 标记 visited class Solution { public:// dfs 染色const int direction[4][2] {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};void dfs(vector<vector<char>>& grid, vector<vector<bool>>& visited, int x…

.NET NoSQL 嵌入式数据库 LiteDB 使用教程

前言 今天大姚给大家分享一个小巧、快速、轻量级的.NET 开源且免费&#xff08;MIT License&#xff09;的 NoSQL 嵌入式数据库&#xff1a;LiteDB。本篇文章我们主要来讲讲LiteDB在.NET中如何使用。 LiteDB介绍 LiteDB 是一个小巧、快速和轻量级的 .NET NoSQL 嵌入式数据库…

什么是快充协议、支持多协议的USB Type-C受电端取电芯片

随着快充技术的不断发展&#xff0c;传统的慢充模式已经满足不了消费者对充电效率的要求。有了快充技术的支持很大程度的缩短了我们的充电时间&#xff0c;给我们的生活带来了很多便利。 什么是快充协议 快充协议是快充技术的核心&#xff0c;现如今市面上已经有很多种快充协议…

打破常规,BD仓储物流的效能提升!

当前&#xff0c;随着国家战略的推进&#xff0c;JS与民用领域的融合不断加深&#xff0c;物流业也步入了军民融合的新时代。在智能仓储物流方面&#xff0c;JS物流的智能化进展受到了BD系统的高度关注和重视。 一、建设JS仓储物流RFID基础设施 JS物流领域引入RFID技术的基础工…

代码随想录算法训练营Day31 | 455.分发饼干、376.摆动序列、53.最大子数组和

目录 455.分发饼干 376.摆动序列 53.最大子数组和 455.分发饼干 题目 455. 分发饼干 - 力扣&#xff08;LeetCode&#xff09; 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c…

论文翻译 | Fairness-guided Few-shot Prompting for LargeLanguage Models

摘要 大型语言模型已经显示出令人惊讶的执行上下文学习的能力&#xff0c;也就是说&#xff0c;这些模型可以通过对由几个输入输出示例构建的提示进行条件反射&#xff0c;直接应用于解决大量下游任务。然而&#xff0c;先前的研究表明&#xff0c;由于训练示例、示例顺序和提示…

HTML的介绍

HTML HTML是一种超文本标记语言,超文本是指,除了文本之外,还可能包含图片,音频,或者评注等的 文本形式,比文本强大,通过链接和交互方式来组织和呈现信息.标记语言是指,由标签构成的语言.HTML定义了多种不同的标签,用来表示不同的内容. 标签的介绍: 1.<h3> 三级 </h3&…

java多态-cnblog

java多态 细分的重载会增加代码量&#xff0c;降低易用程度 定义一个类&#xff0c;继承所有类的对象&#xff0c;根据向上转型可以让每个类的对象都调用初始类的方法&#xff0c;在方法中设置判断&#xff0c;不同的对象导致方法做不同的事&#xff0c;这就是多态 写一个灯…

视频监控汇聚平台Liveweb安防监控平台实现接入监控视频集中管理方案

随着各行业数字化转型的不断推进&#xff0c;视频监控技术在行业内的安防应用及管理支撑日益增多。然而&#xff0c;由于前期规划不清晰、管理不到位等问题&#xff0c;视频监管系统普遍存在以下问题&#xff1a; 1. 各部门单位在视频平台建设中以所属领域为单位&#xff0c;导…

博客项目自动化测试(一)

1. 确认博客系统的环境搭建 http://49.235.129.183:8080/java109_blog_system/blog_list.html&#xff0c;即可访问我的小项目&#xff1b; 2. 确定测试用例 测试用例如下所示&#xff1a; 3. 关于登录的测试用例 3.1 初始化和退出浏览器 代码如下&#xff1a; package Blo…

《大道平渊》· 廿贰 —— 杀心篇:独立人格的形成

《大道平渊》 独立人格的形成&#xff0c;在杀心的过程中会越来越完备。 在这个漫长的过程中&#xff0c;你会一次次击碎自己固有的三观&#xff0c;慢慢再修复你的三观。 . 不要认为一个人的明白&#xff0c;都是恍然大悟&#xff0c;都是碰到了高人指点。 并不是这样的&a…

面试还搞不懂redis,快看看这40道面试题

Redis 面试题 1、什么是 Redis?. 2、Redis 的数据类型&#xff1f; 3、使用 Redis 有哪些好处&#xff1f; 4、Redis 相比 Memcached 有哪些优势&#xff1f; 5、Memcache 与 Redis 的区别都有哪些&#xff1f; 6、Redis 是单进程单线程的&#xff1f; 7、一个字符串类…

python安装插件

报错 E:\pythonProject\pythonProject_JD\Scripts\python.exe E:\浏览器下载\pythoncode\pythonProject_JD\car.py Traceback (most recent call last): File "E:\浏览器下载\pythoncode\pythonProject_JD\car.py", line 5, in <module> from selenium…

双向数据库迁移工具:轻松实现 MySQL 与 SQLite 数据互导

项目概述与作用 该项目的核心是实现 MySQL 和 SQLite 两种数据库之间的数据迁移工具。它能够轻松地将 MySQL 数据库中的数据导出为 SQLite 数据库文件&#xff0c;反过来也可以将 SQLite 数据库中的数据上传到 MySQL 数据库中。这个双向迁移工具非常适用于&#xff1a; 数据库备…

LeetCode15.三数之和

题目链接&#xff1a;15. 三数之和 - 力扣&#xff08;LeetCode&#xff09; 1.常规解法&#xff08;会超时&#xff09; 由于这道题需要排除相同的三元组&#xff0c;则可以先将目标数组从小到大排序&#xff0c;再遍历数组找到每个符合条件的三元组&#xff0c;若结果中不包…

2.JVM性能调优之JVM内存模型深度剖析与优化

1 JDK体系结构 2 Java语言的跨平台特性 3 JVM整体结构及内存模型 3.1 堆内存划分 public class Demo {public static void main(String[] args) {Demo demo new Demo();int rs demo.compute();System.out.println(rs);}public int compute() {int a 1;int b 3;int c (a b…

01 为什么要学习数据结构与算法

为什么要学习数据结构与算法 一、问题提出 ​ 最早计算机的设计初衷主要用于军事上枪炮的弹道计算和火力表的测试&#xff0c;后来更多的用于科学计算&#xff0c;即数值类的计算&#xff0c;而现在&#xff0c;计算机深入到日常生活的各个方面&#xff0c;其计算的数据早已从…

博客搭建之路:Netlify将url重定向到小写问题

文章目录 Netlify将url重定向到小写问题 Netlify将url重定向到小写问题 hexo版本5.0.2 npm版本6.14.7 next版本7.8.0 前两天将博客从vercel改为托管到Netlify上&#xff0c;本来运行的挺流畅的。但是今天我看一篇博客的评论时突然发现&#xff0c;虽然有评论 但是文章开头的评论…