当前位置: 首页 > news >正文

文件操作<C语言>

导言

        平时我们在写程序时,在运行时申请内存空间,运行完时内存空间被收回,如果想要持久化的保存,我们就可以使用文件,所以下文将要介绍一些在程序中完成一些文件操作。


目录

导言

文件流

文件指针

文件的打开与关闭

打开:

关闭:

文件操作

顺序读写:

单个字符:

fputc函数

 fgetc函数

字符串:

 fputs函数

  fgets函数

格式化:

  fprintf函数

fscanf函数

其他:

  sprintf函数

 

sscanf函数

随机读写:

fseek函数

 ftell函数

 rewind函数

 文件结束判定

feof函数

 ferror函数


文件流

        我们常使用的是标准流,它们在使用C语言编写程序时已经默认打开:

●stdin—标准输入流,大部分从键盘输入,比如scanf函数

●stdout—标准输出流,大部分从显示器输出,比如printf函数

●stderr—标准错误流,大部分从显示器输出

 这三种流,属于FILE*类型的指针,我们常常称为文件指针。


文件指针

        文件指针FILE*都指向了一个包含文件信息的结构体。

每个被使用的文件都会自动开辟一个文件信息区,这个文件信息区存放着文件的各种信息,他被存放在一个结构体中,结构体的类型是由系统命名的,命名为FILE。

vs2013这个文件类型声明
struct _iobuf {char *_ptr;int _cnt;char *_base;int _flag;int _file;int _charbuf;int _bufsiz;char *_tmpfname;
};
typedef struct _iobuf FILE;//typedef重命名struct _iobuf为FILE

这样我们在后面使用时创建一个FILE*型的指针,就可以指向任意一个文件信息区(结构体变量)了。

放一张bit课件的图:


文件的打开与关闭

        前面我们提到在C语言中默认打开的流只有标准流,那么我们想要完成文件操作时,那么我们就得先打开文件流,在完成操作后再关闭文件流。

打开:

使用函数fopen()打开文件

函数参数及其返回值

FILE* fopen(const char* filename,const char* made);
//filename:文件名(文件路径)
//made:打开方式
//返回值:FILE*,一个指向filename文件信息区的文件指针,执行失败返回NULL

注意点

●关于参数filename两种表达方式:

绝对路径:从根目录开始创建(C/D盘),任何文件都可访问,如:c:\code\test.txt

在C语言中地址是个字符串,\会被当做转义字符,那么我们可以使用\\或者/的方式来代替

相对路径:以当前路径为基础访问,“.”表示当前路径,“..”表示上一层路径。如:
假设我的当前路径为c:\cyuyan\code\test.txt
我的桌面路径:c:\cyuyan\code\desktop
我想用相对路径访问我的桌面:..\desktop\
相对路径在本目录访问文件时常常会省略.\,直接使用文件名+后缀的方式访问
●关于常用参数mode:
●为了输入(读)数据, mode为“r”,存在:打开,不存在:报错
●为了输出(写)数据,并将目标文件内容清空, mode为“w”,存在:打开,不存在:新建一个

使用举例:

文件运行程序前:

 运行程序:

 文件运行程序后:

关于文件打开值得注意的是:mode的参数决定了后续的文件操作的权限,以读的方式打开只能进行一些读的操作,以写的方式打开只能进行一些写的操作。


关闭:

使用函数fclose()关闭文件

函数参数及其返回值

int fclose(FILE* stream);
//stream:文件流
//返回值:成功:0,失败:EOF(-1)

文件打开后不关闭会造成内存泄漏,这与动态内存不free是一个道理,最后记得置NULL。

使用举例:


文件操作

顺序读写:

单个字符:

fputc函数

功能:写单个字符到流。(输出——写)

 函数参数及其返回值

int fputc(int character ,FILE* stream);
//character:单个字符
//stream:文件流
//返回值:成功:写入字符的ASCII码值,失败:EOF(-1)

使用举例:

当前目录下的test.txt文件内容:


 fgetc函数

功能:从流读单个字符。(输入——读)

 函数参数及其返回值

int fgettc(FILE* stream);
//stream:文件流
//返回值:成功:读取字符的ASCII码值,失败:EOF(-1)

使用举例:

我们先在当前目录创建一个test.txt文件,并写入字符b保存。

运行程序打印出fgetc的返回值(这个返回值就是文件内字符的ASCII码值):

 小写字母b的ASCII码值为98,说明我们读取成功。

值得注意的是fgetc和fputc函数只是针对单个字符的,所以文件存在多个字符时,读取时是第一个字符。


字符串:

 fputs函数

功能:写字符串到流。(输出——写)

 函数参数及其返回值

int fputs(const char* str,FILE* stream);
//str:要写入的字符串
//stream:文件流
//返回值:成功:非负整数,失败:EOF(-1),设置errorno

使用举例:

返回0,也是一个非负整数,且大部分编译器都返回0。

 test.txt文件的写入情况:


  fgets函数

功能:从流中读取字符串。(输入——读)

 函数参数及其返回值

char* fgets(const char* str, int num ,FILE* stream);
//str:从流中读取的字符放在这里面
//stream:文件流
//num:读取num-1个字符,最后一个放\0,
//返回值:成功:字符串str首地址,失败:NULL

注意点:

●遇到换行符停止读取,且这个换行符也会被读取到str中,所以在一些特定场景下,为了输出格式别忘了替换掉换行符\n。

●fgets函数还常常运用于标准输入流,因为它只有读取到\n时才停止,会读取空格,使用时,stream参数为stdin。

使用举例:

创建一个存放着两行数据的test.txt文件:

运行fgets程序:

 我们看到它的确读取成功了,打印时没有加\n,打印出来却自动换行了,说明读取了\n,验证了前面的注意点,我们可以看Debug看一下:

值得注意的是fgets还常常用于完成一些标准输入的操作,它会读取空白字符,且它比gets安全。


格式化:

  fprintf函数

功能:格式化数据到流。(输出——写)

 函数参数及其返回值

int fprintf(FILE* stream , const char* format,……);
//stream:文件流
//format:与printf函数中的“字符串”类似,可以放入占位符
//……:可变参数列表,与printf类似
//返回值:成功:写入字符数,失败:EOF(-1)

使用举例:

运行程序后:

fprintf函数与printf函数类似,只是在参数部分多出了文件流,其他参数不变,返回值也是。


fscanf函数

功能:从流中读取格式化数据。(输入——读)

 函数参数及其返回值

int fscanf(FILE* stream , const char* format ,……);
//stream:文件流
//format:"占位符"与scanf函数第一个参数类似
//……:可变列表(变量名)
//返回值:成功:读取个数,失败:EOF(-1)

使用举例:

创建一个test.txt文件,并写入数据:

 运行程序:

可以观察到,fscanf函数与scanf函数类似,只是多出文件流参数, 其他与scanf函数类似,且需要取地址&


其他:

  sprintf函数

功能:格式化数据到字符串。(输出)

 函数参数及其返回值

int sprintf(char* str, const char* format,……);
//str:要写入的字符串
//format:与printf函数中的“字符串”类似,可以放入占位符
//……:可变参数列表,与printf类似
//返回值:成功:写入字符数,失败:EOF(-1)

使用举例:


 
sscanf函数

功能:从字符串格式化数据。(输入)

 函数参数及其返回值

int sscanf(char* str, const char* format,……);
//str:要读取的字符串
//format:与scanf函数中的“字符串”类似,可以放入占位符
//……:可变参数列表,与scanf类似
//返回值:成功:读取项数,失败:EOF(-1)

使用举例:

 这两个函数可以简单理解为字符串与格式化数据的互换函数。


随机读写:

fseek函数

功能:改变光标位置

 函数参数及其返回值

int fseek(FILE* stream , long int offset ,int origin)
//stream:文件流
//offset:相对于参数origin的偏移量
//origin:三个选项:SEEK_SET:文件指针起始位置、SEEK_CUR:文件指针当前位置、SEEK_END:文件指针结束位置
//返回值:成功:0,失败:非0整数并设置errorno

使用举例:

我们先创建一个文件存放helloworld 18:

 运行程序:


 ftell函数

功能:返回文件指针相对于起始位置的偏移量

 函数参数及其返回值

long int ftell(FILE* stream);
//stream:文件流
//返回值:偏移量

使用举例:

 

 


 rewind函数

功能:使文件指针回到起始位置

 函数参数及其返回值

void rewind(FILE* stream);
//stream:文件流
//返回值:无

使用举例:


 文件结束判定

feof函数

功能:判断文件结束原因(返回值0:遇到错误,非0:遇到文件尾)

 函数参数及其返回值

int feof(FILE* stream);
//stream:文件流
//返回值:0:遇到错误,非0:遇到文件尾

使用举例:


 

 ferror函数

功能:判断文件错误状态

 函数参数及其返回值

int feof(FILE* stream);
//stream:文件流
//返回值:非零值(1):遇到错误,0:没错误

这应该是我所有博客中最长的一篇,因为是笔记的原因,然后也不太熟,所以前前后后几天花了6、7小时,最后也没来的及检查一遍,请佬们斧正,封面图是ai生成的。

相关文章:

  • 【Ruby爬虫01】某吃瓜网站图片数据采集
  • 全面理解-Flutter(万字长文,深度解析)
  • Java中的编译时与运行时注解
  • SQL中的DISTINCT用法总结
  • MongoDB Map-Reduce 简介
  • Selenium WebDriver - 网络元素
  • c++中string的用法
  • 通用大模型 vs垂直大模型:AI界的“宫斗大戏”
  • font-spider按需生成字体文件
  • 提升数据库性能的关键方法总结
  • starrocks进行数据的删除
  • 基于深度学习的边缘检测
  • Ubuntu开机后图像化界面消失只有命令行界面
  • Python爬虫实战:批量下载网站图片
  • Elasticsearch如何聚合查询多个统计值,如何嵌套聚合?并相互引用,统计索引中某一个字段的空值率?语法是怎么样的
  • @angular/forms 源码解析之双向绑定
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • Android Volley源码解析
  • Angular 2 DI - IoC DI - 1
  • CentOS7 安装JDK
  • Consul Config 使用Git做版本控制的实现
  • extjs4学习之配置
  • java多线程
  • leetcode386. Lexicographical Numbers
  • Meteor的表单提交:Form
  • React as a UI Runtime(五、列表)
  • React-生命周期杂记
  • Redis 中的布隆过滤器
  • 反思总结然后整装待发
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • 一、python与pycharm的安装
  • 直播平台建设千万不要忘记流媒体服务器的存在 ...
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • #Linux(Source Insight安装及工程建立)
  • #使用清华镜像源 安装/更新 指定版本tensorflow
  • (javascript)再说document.body.scrollTop的使用问题
  • (MonoGame从入门到放弃-1) MonoGame环境搭建
  • (Qt) 默认QtWidget应用包含什么?
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (二)基于wpr_simulation 的Ros机器人运动控制,gazebo仿真
  • (免费领源码)Python#MySQL图书馆管理系统071718-计算机毕业设计项目选题推荐
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • (删)Java线程同步实现一:synchronzied和wait()/notify()
  • (十六)一篇文章学会Java的常用API
  • (一)Java算法:二分查找
  • (转)大型网站的系统架构
  • .NET Core工程编译事件$(TargetDir)变量为空引发的思考
  • .NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)
  • .NET 中 GetHashCode 的哈希值有多大概率会相同(哈希碰撞)
  • .NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)...
  • .NET导入Excel数据
  • .NET平台开源项目速览(15)文档数据库RavenDB-介绍与初体验
  • .net与java建立WebService再互相调用
  • [<死锁专题>]
  • [10] CUDA程序性能的提升 与 流