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

文件相关操作的函数和文件操作

C语言文件操作

1.什么是文件 

磁盘上的文件是文件,但是在程序设计中,我们一般谈的文件有两种:程序文件、数据文件

1.1程序文件
包括源程序文件(后缀为.c), 目标文件(windows环境后缀为.obj), 可执行程序(windows环境后缀为.exe)

1.2数据文件
文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内
容的文件。

1.3文件名
一个文件要有一个唯一的文件标识,以便用户识别和引用。
文件名包含3部分:文件路径 + 文件名主干 + 文件后缀
例如: c : \code\test.txt
为了方便起见,文件标识常被称为文件名。

2.文件的打开和关闭

2.1文件指针
缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及
文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名FILE.

例如, VS2013编译环境提供的 stdio.h 头文件中有以下的文件类型申明:

 

综上所述:
不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异
每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息
使用者不必关心细节
一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便

下面我们可以创建一个FILE*的指针变量:

 

定义pf是一个指向FILE类型数据的指针变量。可以使pf指向某个文件的文件信息区(是一个结构体变量)
通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联的文件

 

 


2.2打开和关闭文件

1.文件在读写之前应该先打开文件,在使用结束之后应该关闭文件
2.在编写程序的时候,在打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。
3.ANSIC 规定使用fopen函数来打开文件,fclose来关闭文件。

fopen和fclose两个函数的传参和函数返回类型

文件的打开方式如下:

 

 使用实例:

文件的读分为两种:1.顺序读写   2.随机读写

4.文件的顺序读写

有以下几个函数:

下面是每个函数的参数和返回类型:

1.字符输入输出函数:fgetc和fputc
函数fgetc的函数传参和函数返回类型:
int fgetc(FILE* stream);
注:返回的int类型就是读到的那个字符的ASCALL码值

函数fputc的函数传参和函数返回类型
int fputc(int character, FILE* stream);

2.文本行的输入输出函数:fgets和fputs
函数fgets的函数传参和函数返回类型
char* fgets(char* str, int num, FILE* stream);
str就是读取的字符放到的空间
num是最多读取的多少字符拷贝到str里面去,最多读取num-1个字符,因为函数最后还要放一个\0

函数fputs的函数传参和函数返回类型
int fputs(const char* str, FILE* stream);//把str指向的那个字符串写进stream里面

3.格式化输入输出函数:fscanf和fprintf
函数fscanf的函数传参和函数返回类型
int fscnaf(FILE* stream, const char* format, ....);

函数fprintf的函数传参和函数返回类型
int fprintf(FILE* stream, const char* format, ....);
....是可变参数列表

4.二进制输入和输出函数:fread和fwrite:
函数fread的函数传参和函数返回类型
size_t fread(const void* ptr, size_t size, size_t count, FILE* stream);
ptr是指那个被读出元素存放的地址
size就是要写的每一个元素的大小
count就是元素个数

 函数fwrite的函数传参和函数返回类型
size_t fwrite(const void* ptr, size_t size, size_t count, FILE* stream);
ptr是指那个要被写的数据的地址
size就是要写的每一个元素的大小
count就是元素个数

函数的使用1(写文件)(fputc)

 

函数的使用2(读文件)(fgetc) 

函数的使用3(读文件)(fputs)

 函数的使用4(读文件)(fgets)

函数的使用5(写文件)(fprintf)

函数的使用6(读文件)(fscanf)

 

函数的使用7(二进制写文件)(fwrite)

 

函数的使用8(二进制读文件)(fread)

 

对比一组函数:
scanf/fscanf/sscanf
printf / fprintf / sprintf

第一组:scanf和printf
scanf:从键盘上读取格式化的输入数据--针对的是stdin流
printf:把数据写到输出屏幕上--针对的是stdout流

第二组:fscanf和fprintf
fscnaf:针对所有输入流的格式化输入语句--既可以针对打开的文件,也可以针对stdin
fprintf:针对所有输出流的格式化输出函数--即可以针对stdout,也可以针对打开的文件

第三组:sscnaf(可以把字符串的内容转换程结构体)和sprintf(可以把一个结构体数据转换程字符串)
sscanf:从一个字符串中,还原出一个格式化的数据
sprintf:把一个个格式化的数据,存放(转换)在一个字符串中


5.文件随机读写

5.1 fseek函数
根据文件指针的位置和偏移量来定位文件指针

函数传参和函数返回类型
int fseek(FILE* stream, long int offset, int origin);
stream是文件指针的起始指针
offset是偏移量,向后偏移是正数,向前偏移是负数
origin是指从哪里开始,它有三个选项,分别是SEEK_SET、SEEK_CUR、SEEK_END
SEEK_SET是指从文件的起始位置算器起
SEEK_CUR是指当前文件指针的位置
SEEK_END是指文件的末尾

使用例子:

5.2 ftell函数
返回文件指针相对于起始位置的偏移量

函数返回类型和函数传参
long int ftell(FILE* stream);


函数使用例子:

5.3 rewind函数
让文件指针的位置回到文件的起始位置
相当于fseek(pf,0,SEEK_SET)

函数传参和函数返回类型
void rewind(FILE* stream);


函数使用例子

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

根据数据的组织形式,数据文件被称为文本文件或者二进制文件。
数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件。
如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。
一个数据在内存中是怎么存储的呢?
字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。
如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而二进制形式输
出,则在磁盘上只占4个字节(VS2013测试)。

代码测试:

在内存中调试应该这样看它:

 

 

 

 

7.文件读取结束的判定

被错误使用的feof
牢记:在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束。
而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束。

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


正确的使用:
1.文本文件的例子:

feof和ferror函数:
首先,文件读取结束了,想知道文件读取结束的原因
feof--如果返回真,就说明是文件正常读取遇到了结束标志而结束的
ferror--如果返回真,就说明是文件在读取过程中出错了,而结束了,是一种外因的结束,判断为什么结束

2.二进制文件的例子:

8.文件缓冲区 

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

 

 

 

 

 

 

 

 

 

 

 

 

http://www.xdnf.cn/news/18676.html

相关文章:

  • AlexNet读取数据集 与VGG-11网络
  • 视频编码异常的表现
  • `strchr` 字符串查找函数
  • C++中的右值引用与通用引用:std::move与std::forward的正确使用 (Effective Modern C++ 条款25)
  • 《CF1245D Shichikuji and Power Grid》
  • 嵌入式学习 day57 驱动-驱动框架
  • 国产CANFD芯片技术特性与应用前景综述:以ASM1042系列为例
  • Java试题-选择题(14)
  • 番茄(西红柿)叶片病害检测数据集:12k+图像,10类,yolo标注
  • 2025-08-22 Python进阶10——魔术方法
  • 从原理到实践:朴素贝叶斯算法的魅力解析
  • 构建城市数字孪生底座:深度解析智慧城市全景视频拼接融合解决方案
  • ingress和service区别
  • 未来已来?AI 预测技术在气象、金融领域的应用现状与风险警示
  • python3GUI--Joy音乐播放器 在线播放器 播放器 By:PyQt5(附下载地址)
  • Java面试-== 和 equals() 方法的区别与实现原理
  • Unreal Engine UE_LOG
  • 电脑芯片大的32位与64位指的是什么
  • 【数据结构】B+ 树——高度近似于菌丝网络——详细解说与其 C 代码实现
  • 面向RF设计人员的微带贴片天线计算器
  • AI领域的语义空间是什么?
  • ES6变量与解构:let、const与模板字符串全解析
  • 「越短越合法」型滑动窗口
  • 解释一下,Linux,shell,Vmware,Ubuntu,以及Linux命令和shell命令的区别
  • 111、【OS】【Nuttx】【周边】效果呈现方案解析:-print0 选项
  • Linux操作系统编程——网络
  • 第二阶段WinFrom-6:文件对话框,对象的本地保存,序列化与反序列化,CSV文件操作,INI文件读写
  • 08.21总结
  • Claude Code 三类.md文件
  • Day2--HOT100--283. 移动零,11. 盛最多水的容器,15. 三数之和