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

news2024/10/10 16:34:06

在这里插入图片描述

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

在这里插入图片描述

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

顺序读写数据常用函数

函数名调用形式功能返回值
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.coloradmin.cn/o/2202502.html

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

相关文章

诺贝尔物理学奖向机器学习与神经网络致敬,科学边界的跨越与未来的启示

2024年诺贝尔物理学奖首次颁发给机器学习与神经网络领域的研究者&#xff0c;这一历史性事件打破了人们对诺贝尔物理学奖的传统认知&#xff0c;激起了全球学术界、科技界的广泛讨论。这一变化不仅标志着科学边界的延伸&#xff0c;也体现出人工智能技术对现实世界的深远影响。…

剪切走的照片:高效恢复与预防策略

一、剪切走的照片现象描述 在日常的数字生活中&#xff0c;照片作为记录生活点滴、工作成果的重要载体&#xff0c;其重要性不言而喻。然而&#xff0c;有时我们可能会遇到一种令人头疼的情况&#xff1a;原本打算通过剪切操作将照片移动到另一个位置&#xff0c;却意外地发现…

Java 8 的内存结构

Java8内存结构图 虚拟机内存与本地内存的区别 Java虚拟机在执行的时候会把管理的内存分配成不同的区域&#xff0c;这些区域被称为虚拟机内存&#xff0c;同时&#xff0c;对于虚拟机没有直接管理的物理内存&#xff0c;也有一定的利用&#xff0c;这些被利用却不在虚拟机内存…

Qt5.15.2静态编译 MinGW with static OpenSSL

如果想用VS2017编译,可参考:Qt5.15.2静态编译 VS2017 with static OpenSSL 一.环境 系统:Windows 10 专业版 64位 编译器:MinGW 8.1.0 第三方工具:perl,ruby和python PS:经验证,用MinGW 12.1.0来编译Qt5.15.2会报错 我用Phthon 2.7.18虽然可以编过,但是强烈建议Pyth…

0.0.0.0 127.0.0.1等几个特殊的IP地址

0.0.0.0 127.0.0.1 localhost 255.255.255.0 255.255.255.255 这都是些什么地址&#xff0c;代表了什么意思。 网络为系统服务器&#xff0c;系统需要网络。 这些地址在系统和网络都存在&#xff0c;作用和意思甚至基本相同。 一、0.0.0.0 在路由中&#xff1a;0.0.0.0表…

【面试宝典】深入Python高级:直戳痛点的题目演示(上)

目录 &#x1f354; 你知道深浅拷⻉的区别吗&#xff1f; &#x1f354; 字典反转&#xff0c;列表反转的实现&#xff1f; &#x1f354; 装饰器是什么&#xff0c;什么场景⽤到装饰器&#xff0c;举个例⼦&#xff1f; &#x1f354; 装饰器的实质是什么…

定时关机(python)

内容 为了更简单地实现定时关机&#xff0c;不必去记繁琐的命令行&#xff0c;于是搞了一个gui出来 基于python和Windows命令行实现&#xff0c;核心为&#xff1a; shutdown -s -t 60 代码 # -*- coding: utf-8 -*- # Environment PyCharm # File_name autoShutdown…

【教学类-36-10】20241010职业抽卡(midjounery-niji)(涂色、裁剪、游戏)

背景需求 昨天在户外玩了角色游戏&#xff0c;受道具所限&#xff08;只有烧烤做饭锅子材料&#xff09;&#xff0c;所有的孩子都只玩了烧烤店、娃娃家做饭的内容&#xff0c;扮演的都是爸妈、厨师等工作 今天从以前的纸类学具中找出一套数量相对较多的“职业涂色卡” 学具代…

2024中国新媒体技术展 | 蓝海创意云vLive虚拟直播即将亮相!

​​ 2024中国新媒体大会由中央宣传部指导&#xff0c;中华全国新闻工作者协会、湖南省人民政府联合主办&#xff0c;旨在推动媒体深度融合发展&#xff0c;促进新闻事业高质量发展&#xff0c;为中国式现代化贡献力量。中国新媒体技术展&#xff08;CMTE&#xff09;是中国新…

设计模式、系统设计 record part05

行为型模式 模板方法模式、解释器模式是类型为模式&#xff0c; 模板方法模式 模板方法&#xff08;Template Method&#xff09; 抽象类&#xff08;Abstract Class&#xff09; 抽象方法&#xff08;Abstract Method&#xff09; 具体方法&#xff08;Concrete Method&#x…

详细解读“霸王面”战术

“霸王面”战术是指在没有得到雇主面试通知的情况下&#xff0c;强行加入面试&#xff0c;以此争取工作机会的求职策略。以下将以3000字左右的篇幅&#xff0c;通过生动形象的例子详细解释这一战术。 一、背景介绍 在当今竞争激烈的就业市场中&#xff0c;求职者需要经历网申…

2.1 App测试与发布指南

欢迎大家订阅【软件测试】 专栏&#xff0c;开启你的软件测试学习之旅&#xff01; 文章目录 前言1 系统架构2 APP测试范围3 APP发布流程4 发布策略 前言 在当今数字化时代&#xff0c;移动应用程序&#xff08;APP&#xff09;和Web应用程序是两种主要的软件交付方式。本文详…

arm imx6ull docker启动失败问题查找与解决 内核配置相关

1、增加POSIX Message qeue&#xff1a;could not get initial namespace: no such file or directory CONFIG_POSIX_MQUEUEy 2、增加namespace failed to set to initial namespace CONFIG_NAMESPACESy 3、创建网络失败&#xff0c;veth配置&#xff1a;docker create endp…

40条经典ChatGPT论文指令,圈定选题和进行论文构思

目录 1、用ChatGPT圈定选题范围2、用ChatGPT生成研究方法和思路3、用ChatGPT扩展论文观点和论证4、用ChatGPT辅助论文结构设计5、如何直接使用ChatGPT4o、o1、OpenAI Canvas6、OpenAI Canvas增强了啥&#xff1f;7、编程功能增强 &#x1f447; ChatGPT o1网页入口在文末&#…

光路科技TSN交换机:驱动自动驾驶技术革新,保障高精度实时数据传输

自动驾驶技术正快速演进&#xff0c;对实时数据处理能力的需求激增。光路科技推出的TSN&#xff08;时间敏感网络&#xff09;交换机&#xff0c;在比亚迪最新车型中的成功应用&#xff0c;显著推动了这一领域的技术进步。 自动驾驶技术面临的挑战 自动驾驶系统需整合来自雷达…

CentOS系统解压缩.7z后缀的文件

先安装工具 sudo yum install p7zip p7zip-plugins 解压缩 7z x mvtec3d.7z x参数表示解压并保持原有目录结构。 有报错 7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21 p7zip Version 16.02 (localeen_US.UTF-8,Utf16on,HugeFileson,64 bits,64 CP…

马志威新剧《黑色月光》开播 “海王”梁正贤角色再升级

由优酷、TVB联合出品&#xff0c;77工作室制作的《黑色月光》于10月9日在优酷视频上线播出。该剧由知名导演钟澍佳担任总监制&#xff0c;杨茜尧、马志威等TVB演员主演&#xff0c;故事以公关行业为背景&#xff0c;讲述了职场女性余满月曾被富豪蒋家害得家破人亡&#xff0c;精…

C++ 算法学习——1.8 单调队列算法

单调队列&#xff08;Monotonic Queue&#xff09;是一种特殊类型的队列&#xff0c;通常用于解决一些数组或序列相关的问题。和单调栈类似&#xff0c;单调队列也具有一些特定的性质&#xff0c;在解决一些问题时非常有用。以下是关于单调队列的一些重要点&#xff1a; 定义&a…

《14天从0到1学Java》第二天之01Java中的分支结构if语句

Hello&#xff0c;大家好&#xff0c;我是Feri&#xff0c;一枚十多年的程序员&#xff0c;研究生&#xff0c;关注我&#xff0c;且看一个平凡的程序员如何在自我成长&#xff0c;也为各位小伙伴提供编程相关干货知识&#xff0c;希望在自我蜕变的路上&#xff0c;我们一起努力…

解决SqlServer自增主键使用MybatisPlus批量插入报错问题

报错 SqlServer 表中主键设置为自增&#xff0c;会报以下错误。 org.springframework.jdbc.UncategorizedSQLException: Error getting generated key or setting result to parameter object. Cause: com.microsoft.sqlserver.jdbc.SQLServerException: 必须执行该语句才能获…