C语言--文件操作

1.标准流

stdin - 标准输⼊流,在⼤多数的环境中从键盘输⼊,scanf函数就是从标准输⼊流中读取数据。
stdout - 标准输出流,⼤多数的环境中输出⾄显⽰器界⾯,printf函数就是将信息输出到标准输出
流中。
stderr - 标准错误流,⼤多数环境中输出到显⽰器界⾯。
这是默认打开了这三个流,我们使⽤scanf、printf等函数就可以直接进⾏输⼊输出操作的。
stdin、stdout、stderr 三个流的类型是: FILE * ,通常称为⽂件指针。
C语⾔中,就是通过 FILE* 的⽂件指针来维护流的各种操作的。

2.文件的打开和关闭

#include<stdio.h>
int main()
{FILE* pf = fopen("text.txt", "w");if (pf == NULL){perror("fopen");return 1;}fclose(pf);pf = NULL;return 0;
}

这个是所有文件,无论进行任何操作都会经历的文件的打开和关闭,中间可能我们会进行文件的读和文件的写,以及对于文件的修改等等操作。

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

数据在内存里面以二进制的形式存储,如果不进行转换输出到文件里面就是二进制文件;

如果转换成ASCII形式,以ASCII形式存储的文件就是文本文件;

对于二进制的文件,我们无法看懂,如果是在VS上面,可以使用二进制编辑器进行转换,这样的话,文件里面的内容就会以16进制的形式显示出来,我们这个时候就可以正常阅读文件了;

4.文件的读和写

我们首先要清楚什么是文件的读和写?

文件的读就是从文件里面获取数据,文件的写就是从程序向文件里面写入数据;

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

我们这段代码是进行了读文件的操作,那么这个文件必须是存在的,只有这样我们才能够进行相应的操作,但是我们路径下面是没有这个文件的,所以perror就会显示对应的错误;如果已经新建了这个文件,那么程序运行就不会显示任何的错误;

如果我们是一些的方式,目录就会自己新建生成test.txt文件的;

5.文件的顺序读写函数

(1)fputc函数

这个函数具有2个参数,我们可见就是把第一个参数(字符)写到第二个参数(文件)里面去;

int main()
{FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}fputc('a', pf);fputc('b', pf);fputc('c', pf);fclose(pf);pf = NULL;return 0;
}

上面的代码是一次写入一个字符,我们也可以利用for循环语句,一次写入多个字符,下面的这段代码就是写入26个字符;

int main()
{FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}char ch = 0;for (ch = 'a'; ch < 'z'; ch++){fputc(ch, pf);}fclose(pf);pf = NULL;return 0;
}

(2)fgetc函数

这个函数的返回值是int类型的,如果成功读取返回就是对应字符的ASCII值,如果是遇到文件的末尾或者读取失败,就会返回EOF(数值是-1);我们可以利用while循环读取文件里面的字符;

int main()
{FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}int i = 0;int ch = 0;while((ch=fgetc(pf))!=EOF){printf("%c", ch);}fclose(pf);pf = NULL;return 0;
}

(3)fputs函数

上面的两个函数一次只能够读一个字符或者是写一个字符,我们写入字符串(也就是一次性写一堆字符)就可以使用fputs函数;

int main()
{FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}fputs("hello world", pf);fputs("hello china", pf);//关闭文件fclose(pf);pf = NULL;return 0;
}

我们可以多次进行写入,但是这个函数是没有换行的功能的,需要我们手动进行换行,也就是添加斜杠n进行换行;

(4)fgets函数

int main()
{FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}char arr[10] = { 0 };fgets(arr, 10, pf);//关闭文件fclose(pf);pf = NULL;return 0;
}

这个函数有3个参数,第一个是指针数组(我们读取的数据放进去),第二个参数是读取的个数,第三个参数是文件流(就是从哪个文件里面读取);

实际上,我们这里写的是10个字符,他只会读取9个字符,最后一个留给了斜杠0;

如果我们读取10个字符,文件只有5个字符,这个时候就会读取文件末尾的斜杠0读取进来(这个过程我们通过调试可以观察到),下面是调试的截图,读者可以自行尝试:

(5)fprintf函数

这个函数和我们熟知的printf函数参数很相似,就是多了一个文件流参数:对于初学者,我们可先按照printf函数的形式进行写代码,最后加上我们的文件流就可以了:

struct S
{char name[20];int age;float score;
};
int main()
{struct S s = { "章山",18,99.3f };FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}fprintf(pf,"%s %d %f", s.name, s.age, s.score);//关闭文件fclose(pf);pf = NULL;return 0;
}

这个里面我们是创建了一个结构体类型的变量,最后打印姓名,年龄和成绩,由此可见,写法和printf相似,就是在前面加上文件流pf,这样就可以写入文件里面去了;

(6)fscanf函数

我们把写进去的数据读出来,最后我们使用printf打印到我们的屏幕上;

因为fscanf要地址,name这个数组已经是地址,不需要加上取地址符号,其他的两个要加上取地址符号;


上面我们介绍的六个函数,适用于所有的流,既可以是文件流pf(我们上面的案例使用的全部是pf文件流),也可以是标准流,例如我们把pf改为stdout这样就可以把内容打印在屏幕上面(使用pf直接写到文件里面去了);


(7)fwrite函数

int main()
{int arr[5] = { 1,2,3,4,5 };FILE* pf = fopen("test.txt", "wb");if (pf == NULL){perror("fopen");return 1;}int sz = sizeof(arr) / sizeof(arr[0]);fwrite(arr, sizeof(arr[0]), sz, pf);fclose(pf);pf = NULL;return 0;
}

这个函数有4个参数,第一个是地址,第二合适单个元素的大小,第三个是个数(写的个数),第四个是文件流,这个是以二进制写入的(wb)我们看不懂,

我们可以使用下面的函数fread同样以二进制的方式读出来;


(8)fread函数

int main()
{int arr[5] = { 1,2,3,4,5 };FILE* pf = fopen("test.txt", "wb");if (pf == NULL){perror("fopen");return 1;}int sz = sizeof(arr) / sizeof(arr[0]);fread(arr, sizeof(arr[0]), sz, pf);int i = 0;for (i = 0; i < 5; i++){printf("%d ", arr[i]);}fclose(pf);pf = NULL;return 0;
}

上面的读出前提是我们已经知道数组大小,如果不知道,我们可以利用循环读取:

我们之所以能够这样做是因为fread的返回值是读取成功的字符的个数,我们利用fread的返回值,读取到最后就可以自动退出循环,这样即使不知道数组的大小,我们也可以进行打印;


78两个函数是以二进制的方式进行读和写的。


6.一组函数的对比

int main()
{char arr[300] = { 0 };struct S s = { "章山",18,99.3f };FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}sprintf(arr, "%s %d %f", s.name, s.age, s.score);printf("%s\n", arr);struct S t = { 0 };sscanf(arr, "%s %d %f", t.name, &(t.age), &(t.score));printf("%s %d %f", t.name, t.age, t.score);//关闭文件fclose(pf);pf = NULL;return 0;
}

sprintf和sscanf函数,第一个是把格式化的数据转化为字符串,第二个是把字符串转换为格式化的数据;

7.文件的随机读写函数

(1)fseek函数

根据⽂件指针的位置和偏移量来定位⽂件指针(⽂件内容的光标)。
第三个参数有以下的多种形式可供我们选择;
第一次打印a,偏移之后在读取,就会打印f了;
如果第三个参数写的是SEEK_END相当于指向了文件的末尾,如果我们还想打印f就需要设置第二
个参数是-7,相当于从末尾偏移7个长度
(2)ftell函数
返回⽂件指针相对于起始位置的偏移量
还是上面的例子,我们计算的就是f相对于起始位置的偏移量,也就是5,打印的结果就是5;
我们可以使用fseek(pf,0,SEEK_END),这个时候使用ftell(pf)就是计算的字符串的长度;
(3)rewind函数
让⽂件指针的位置回到⽂件的起始位置;
这个里面我们本来已经偏移4个单位长度,rewind直接回到起点,打印的还是字符a;

8.文件读取结束

牢记:在⽂件读取过程中,不能⽤feof函数的返回值直接来判断⽂件的是否结束。
feof 的作⽤是:当⽂件读取结束的时候,判断是读取结束的原因是否是:遇到⽂件尾结束
fgetc读取过程返回EOF,就说明读取结束;
fgets读取过程返回NULL,就说明读取结束;
如果是读取到末尾结束了,feof返回的是非0数字,我们使用if语句进行判断;
由此可见,feof是判断文件是否因为读取到末尾才结束;
否则使用ferror判断读取错误(如果是读取出错结束,ferror返回非0数字),perror打印错误原因。

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

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

相关文章

丰诺畅机电科技将莅临2024年第13届生物发酵展

参展企业介绍 无锡丰诺畅机电科技有限公司&#xff0c;是一家分离设备专业制造公司&#xff0c;集开发、设计、制造、销售、服务于一体;具有专业的生产技术&#xff0c;先进的生产工艺&#xff0c;精良的制造设备&#xff0c;完善的检测手段;为满足不同用户的过滤需求&#xf…

HTTP/UDP/TCP/IP网络协议

文章目录 计算机网络基础HTTPUDPTCP连接管理(三次握手/四次挥手)TCP可靠传输(确认答应)超时重传滑动窗口流量控制拥塞控制延时应答捎带应答粘包问题其他 IP数据链路层MUT 相关问题TCP会粘包、UDP永远不会粘包 学习博客 计算机网络基础 OSI模型定义了网络互连的七层框架&#x…

esp32控制舵机---待完善

舵机有三个引脚&#xff0c;分别是电源、电源GND和信号线。如下图所示&#xff1a; ESP32-WROOM-32E的引脚的定义如下&#xff1a; 图来自乐鑫官网:ESP32-DevKitC V4 入门指南 - ESP32 - — ESP-IDF 编程指南 v5.2.1 文档 硬件连接图&#xff1a; 待补充

013——超声波模块驱动开发(基于I.MX6uLL与SR04)

目录 一、 模块介绍 1.1 产品特色 1.2 产品实物图 1.3 接口定义 1.4 测距调节 1.5 模块工作原理 1.6 注意 二、 编码思路 三、 驱动程序 四、 应用程序 五、 Makefile 六、 其它及实验 一、 模块介绍 超声波测距模块是利用超声波来测距。模块先发送超声波&#xf…

边缘计算盒子与云计算:谁更适合您的业务需求?

边缘计算盒子和云计算&#xff0c;这两个概念听起来可能有点复杂&#xff0c;但其实它们就是两种不同的数据处理方式。那谁更适合您的业务需求呢&#xff1f;咱们来详细说说。 边缘计算盒子&#xff0c;就像是个小型的数据处理中心&#xff0c;放在离你业务现场比较近的地方。它…

WPS二次开发专题:如何获取应用签名SHA256值

作者持续关注WPS二次开发专题系列&#xff0c;持续为大家带来更多有价值的WPS开发技术细节&#xff0c;如果能够帮助到您&#xff0c;请帮忙来个一键三连&#xff0c;更多问题请联系我&#xff08;QQ:250325397&#xff09; 在申请WPS SDK授权版时候需要开发者提供应用包名和签…

美创科技获浙江省网络空间安全协会多项荣誉认可

4月2日&#xff0c;浙江省网络空间安全协会第二届会员大会第一次会议在杭州隆重召开&#xff0c;近180家会员单位代表、数十位特邀专家、嘉宾莅临现场。浙江省委网信办副主任马晓军出席会议并致辞&#xff0c;本次大会由协会秘书长吴铤主持。 凝心聚力&#xff0c;继往开来&…

SAP:无法在插件模式 HTTP 中处理消息 E ** xxx

问题描述&#xff1a;利用post方式接口&#xff0c;返回信息为 无法在插件模式 HTTP 中处理消息 E ** xxx ,如何排查是因为什么问题导致的&#xff1f; 解决方法&#xff1a; 事务码&#xff1a;SE91, 输入消息类&#xff0c;消息编号&#xff0c;点击显示&#xff0c;查看报…

【NLP笔记】LLM应用之AI Agent LangChain实战

文章目录 AI Agent概述LangChain实战构建prompt模版LLM调用调用HuggingFace开源大模型&#xff08;在线&#xff09;调用HuggingFace开源大模型&#xff08;本地&#xff09;调用文心一言 ChainsSingle ChainSequential ChainSimple Sequential ChainComplex Sequential Chain …

【重学C语言】三、C语言最简单的程序

【重学C语言】三、C语言最简单的程序 最简单的程序头文件使用尖括号 < >使用双引号 ""区别与注意事项示例 主函数认识三个错误 常量和变量常量ASCII 码表转义字符 关键字数据类型关键字存储类关键字修饰符关键字控制流程关键字函数相关关键字其他关键字 变量变…

长连接详解

一分钟了解长连接 、短连接、心跳机制与断线重连 - 知乎 (zhihu.com) websocket 实现长连接原理_websocket 是长连接吗-CSDN博客

kettle使用MD5加密增量获取接口数据

kettle使用MD5加密增量获取接口数据 场景介绍&#xff1a; 使用JavaScript组件进行MD5加密得到Http header&#xff0c;调用API接口增量获取接口数据&#xff0c;使用json input组件解析数据入库 案例适用范围&#xff1a; MD5加密可参考、增量过程可参考、调用API接口获取…

Jenkins--任务详解

一、任务类型 Jenkins的主要功能的实现是由执行任务去完成的&#xff0c;常用的任务类型主要有以下三种&#xff1a; 自由风格任务(Free Style Project): 这是Jenkins中最常用的任务类型&#xff0c;允许你自定义各种构建步骤和配置选项&#xff0c;如源码管理、构建触发器、…

JMM内存模型 volatile关键字解析

前言 对于多线程等等的各种操作,相比各位都了然于胸,现在我们来介绍一下更底层一点点的JMM内存模型,其实也是一个很简单的理想的内存模型 注意与JVM的内存模型区分 多线程内存模型主要是基于CPU缓存搭建起来的 这里就区分工作内存和主内存了 我们线程操作的其实是主内存的一个副…

构建第一个JS应用(FA模型)

创建JS工程 若首次打开DevEco Studio&#xff0c;请点击Create Project创建工程。如果已经打开了一个工程&#xff0c;请在菜单栏选择File > New > Create Project来创建一个新工程。选择Application应用开发&#xff08;本文以应用开发为例&#xff0c;Atomic Service对…

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之一 简单视频放大抖动效果

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之一 简单视频放大抖动效果 目录 Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之一 简单视频放大抖动效果 一、简单介绍 二、简单视频放大抖动效果实现原理 三、简单视频放大…

R语言数据挖掘:随机森林(1)

数据集heart_learning.csv与heart_test.csv是关于心脏病的数据集&#xff0c;heart_learning.csv是训练数据集&#xff0c;heart_test.csv是测试数据集。要求&#xff1a;target和target2为因变量&#xff0c;其他诸变量为自变量。用决策树模型对target和target2做预测&#xf…

OpenHarmony实战开发-多设备自适应能力

介绍 本示例是《一次开发&#xff0c;多端部署》的配套示例代码&#xff0c;展示了页面开发的一多能力&#xff0c;包括自适应布局、响应式布局、典型布局场景以及资源文件使用。 说明&#xff1a; 自适应布局能力仅可以保证在外部容器大小在一定范围内变化时&#xff0c;容…

Vue项目中 安装及使用Sass(scss)

普通方法 一、安装使用scss 1. 安装 scss npm install scss --save2. 安装 node-sass 和 sass-loader sass-loader&#xff1a;把 sass编译成css node-sass&#xff1a;nodejs环境中将sass转css 提示&#xff1a;限制 node-sass&#xff0c;sass-loader 版本号&#xff0c;…

【协议篇:Http与Https】

1. Http 1.1 Http的定义 超文本传输协议&#xff08;Hypertext Transfer Protocol&#xff0c;HTTP&#xff09;是用于分布式、协作式和超媒体信息系统的应用层协议。它是互联网上最广泛应用的数据通信协议之一&#xff0c;尤其对于万维网&#xff08;WWW&#xff09;服务而言…