【C】文件操作详解

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

文件操作

什么是文件

磁盘上的文件是文件。

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


程序文件


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


数据文件


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


有时候我们会把信息输出到磁盘上,当需要的时候再从磁盘上把数据读取到内存中使用,这里处理的就是磁盘上文件。


我们里讲的都是数据文件。


文件名

一个文件要有一个唯一的文件标识,以便用户识别和引用。

文件名包含3部分:文件路径+文件名主干+文件后缀

例如: c:\code\test.txt

为了方便起见,文件标识常被称为文件名。


文件类型

文本文件

如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。


二进制文件

数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件。


字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。

如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而二进制形式输出,则在磁盘上只占4个字节。


文件缓冲区

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


也就是说我们从磁盘和内存中间有一个文件缓冲区,从文件中拿数据时,会先放到文件缓冲区中去,当放满以后才会输入到内存,我们也可以通过特殊的手段,提前清空缓冲区。

8d34ed0f51e3444b87ebfb1386c01414.png

文件指针

缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。

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

不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异。

每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不必关心细节。

一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便。

FILE* pc // 文件指针变量

通过文件指针变量能够找到与它关联的文件。

文件的打开和关闭

文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。

在编写程序的时候,在打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。

ANSIC 规定使用fopen函数来打开文件,fclose来关闭文件。


fopen

FILE * fopen ( const char * filename, const char * mode );


打开方式如下:

e1680b22fc27499ea311c5300ae621b9.png

fclose

int fclose ( FILE * stream );


打开和关闭两个函数要配合使用。

举个具体的例子,代码如下;

#include <stdio.h>
int main()
{
  //打开文件
  FILE* pc = fopen("text.txt", "w");
  if (pc == NULL)
  {
    //打开失败,直接返回
    perror("fopen");
    return 1;
  }
  //读写文件
  //关闭文件
  fclose(pc);
  pc = NULL;
  return 0;
}

文件的顺序读写

下图都是一些顺序读写的函数:

4e8944faa8e54f359e2acb8b0a130687.png

fgetc

int fgetc( FILE *stream );


从文件中读一个字符。


fputc

int fputc( int c, FILE *stream );


输出一个字符到文件中。


fgets

char *fgets( char *string, int n, FILE *stream );


从文件中读一行,最多读n-1个字符。


fputc

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


输出一个字符串到文件中去。


fscanf

int fscanf( FILE *stream, const char *format [, argument ]… );


和scanf用法一样,前面多了个指针,可以是文件指针,从文件中读,也可以是标准输入流stdin,从键盘中读入数据。


fprintf

int fprintf( FILE *stream, const char *format [, argument ]…);


和printf用法一样,前面多了个指针,可以是文件指针,输出到文件,也可以用标准输出流stdout输出到屏幕


fwrite

size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );


二进制的写,写count个size大小的buffer指向的内容到stream中去。


fread

size_t fread( void *buffer, size_t size, size_t count, FILE *stream );


二进制的读,从文件中读count个size大小的数据到buffer指向的空间中去。


比较scanf/fscanf/sscanf

sscanf

int sscanf( const char *buffer, const char *format [, argument ] … );


scanf 是从标准输入流中读取格式化的数据

fscanf 是从所有输入流中读取格式化的数据

sscnaf 是从字符串种读取格式化的数据


比较printf/fprintf/sprintf

sprintf

int sprintf( char *buffer, const char *format [, argument] … );


printf 是将格式化的数据输出到标准输出流中去。

fprintf 是将格式化的数据输出到所有输出流中去。

sprintf 是将格式化的数据转化为一个字符串。


文件的随机读写

fseek

根据文件指针的位置和偏移量来定位文件指针。


int fseek( FILE *stream, long offset, int origin );


origin的三个取值:6c51705221684ad3a38449aa3cb33687.png

SEEK_CUR是指指针当前的位置。

SEEK_END是文件末尾位置。

SEEK_SET是文件开始位置。


ftell

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


long int ftell ( FILE * stream );


rewind

让文件指针的位置回到文件的起始位置


void rewind ( FILE * stream );


文件结束的标志

被错误使用的 feof

在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束。

而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束。

文本文件读取是否结束,判断返回值是否为EOF (fgetc),或者NULL(fgets)

例如:

fgetc判断是否为EOF.

fgets判断返回值是否为NULL.

二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。

例如:

fread判断返回值是否小于实际要读的个数。


今天的分享就到这里,感谢大家的关注和支持。

相关文章
突然yml文件不显示绿叶子问题
记一次解决突然yml文件不显示绿叶子问题,原来好好的,今天打开突然就坏了,奇了怪了。。。
436 0
|
10月前
|
人工智能 自然语言处理 监控
通过阿里云向量检索 Milvus 版和通义千问快速构建基于专属知识库的问答系统
通过阿里云向量检索 Milvus 版和通义千问快速构建基于专属知识库的问答系统
240 0
|
编解码 算法 数据安全/隐私保护
CTF图像隐写——“双图”和“图像和像素值转换”
CTF图像隐写——“双图”和“图像和像素值转换”
819 2
|
存储 监控 Java
线上OOM排查
本文介绍了JDK工具的使用方法及其应用场景。首先详细说明了`jps`、`jstack`、`jstat`和`jmap`等工具的基本用法及参数含义,帮助开发者实时监控Java进程的状态,诊断线程问题及内存使用情况。接着介绍了`jvisualvm.exe`和`MemoryAnalyzer.exe`两款内存诊断工具,展示了如何通过这些工具进行内存分析。最后,文章提供了在线上OOM故障排查的具体步骤,并给出了解决方案示例,以便开发者更好地理解和解决实际问题。
470 2
线上OOM排查
|
移动开发 前端开发 JavaScript
10款精美的web前端源码的特效,2024年最新面试题+笔记+项目实战
10款精美的web前端源码的特效,2024年最新面试题+笔记+项目实战
|
KVM 虚拟化
KVM的热添加技术之CPU
这篇文章介绍了如何在KVM虚拟机中热添加CPU资源,包括查看当前CPU配置、修改CPU核心数、永久性修改CPU配置以及注意事项等操作步骤。
423 1
KVM的热添加技术之CPU
|
数据采集 自然语言处理 语音技术
LangChain进阶:创建多模态应用
【8月更文第4天】随着自然语言处理 (NLP) 和计算机视觉 (CV) 技术的不断发展,多模态应用变得越来越普遍。这些应用结合了文本、图像、音频等多种数据类型,以增强用户体验并解决复杂的问题。LangChain 作为一款强大的工具链,可以很好地支持多模态数据的处理,从而开发出具有高度互动性和实用性的应用。
1162 1
|
弹性计算 Java 关系型数据库
分库分表比较推荐的方案
ShardingSphere 绝对可以说是当前分库分表的首选!ShardingSphere 的功能完善,除了支持读写分离和分库分表,还提供分布式事务、数据库治理等功能。另外,ShardingSphere 的生态体系完善,社区活跃,文档完善,更新和发布比较频繁
463 0
|
算法 数据可视化 数据挖掘
大学生必备!GitHub星标破千的matlab教程(从新手到骨灰级玩家)
MATLAB(Matrix Laboratory)是MathWorks公司推出的用于算法开发、数据可视化、数据分析以及数值计算的高级技术计算语言和交互式环境的商业数学软件。 MATLAB具有数值分析、数值和符号计算、工程与科学绘图、数字图像处理、财务与金融工程等功能,为众多科学领域提供了全面的解决方案。
|
分布式计算 DataWorks DataX
DataWorks产品使用合集之DataX的ODPSReader和Tunnel是两种不同的读取MC(原名ODPS)数据的方式吗
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
319 3

热门文章

最新文章