C语言文件操作函数总结

简介: C语言文件操作函数总结

前言:

倘若数据一直存留在内存中,那么我们的程序执行一次后,对应的数据也会跟着丢失,倘若是一些计算性质的程序还好,当时对于需要保留的数据来说,迫切需要一种方式可以将其永久性的保留下来,目前据我所知的有两种方法,第一种是将其存储到对应的数据库中保留下来,第二种则是直接写入文件内部硬盘上(也就是写入磁盘上保存下来)。那么我今天要总结的便是第二种方式,即写入硬盘上保留的方式。

1.计算机的数据基本运转过程:

我们写完的程序,它是怎样经过一系列处理在屏幕上显示出来?我们输入的数据又是如何被计算机接收的呢?数据是怎样进入文件内部的呢?下面便让我们来深入了解一下这些问题:

1.流:

我们程序的数据需要输出到各种外部设备,也需要从外部设备获取数据,不同的外部设备的输⼊输出操作各不相同,为了⽅便程序员对各种设备进⾏⽅便的操作,我们抽象出了流的概念,我们可以把流想象成流淌着字符的河。C程序针对⽂件、画⾯、键盘等的数据输⼊输出操作都是同流操作的。⼀般情况下,我们要想向流⾥写数据,或者从流中读取数据,都是要打开流,然后操作。

如图:

这也就是为什么我们可以使用scanf向内存输入,同时屏幕又可以输出的原因,他们之间的数据流通是依靠这样的一个流来驱动的,数据通过这样的方式可以到达任何地方。那么我们今天所要进行的便是进入硬盘文件这一步骤。

2.标准流:

那为什么我们从键盘输⼊数据,向屏幕上输出数据,并没有打开流呢?

那是因为C语⾔程序在启动的时候,默认打开了3个流:

• stdin - 标准输⼊流,在⼤多数的环境中从键盘输⼊。
• stdout - 标准输出流,⼤多数的环境中输出⾄显⽰器界⾯。
• stderr - 标准错误流,⼤多数环境中输出到显⽰器界⾯。

这是默认打开了这三个流,我们使⽤scanf、printf等函数就可以直接进⾏输⼊输出操作的。

stdin、stdout、stderr三个流的类型是: FILE* ,通常称为⽂件指针。

C语⾔中,就是通过 FILE* 的⽂件指针来维护流的各种操作的。**也就是说,任何关于流数据的掌控和流向,都是由对应的FILE的结构体指针来操控的,我们这里称之为文件指针,接下来的文件操作中,几乎都需要用FILE这个数据类型。

3.文件操作:

1.文件指针:FILE*

缓冲⽂件系统中,关键的概念是“⽂件类型指针”,简称“⽂件指针”。
每个被使⽤的⽂件都在内存中开辟了⼀个相应的⽂件信息区,⽤来存放⽂件的相关信息(如⽂件的名
字,⽂件状态及⽂件当前的位置等)。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系
统声明的,取名FILE.也就是说,我们是通过文件指针来直接操作文件的。

常见形式为:

FILE* pf

2.文件的分类:

1.程序⽂件

程序⽂件包括源程序⽂件(后缀为.c),⽬标⽂件(windows环境后缀为.obj),可执⾏程序(windows

环境后缀为.exe)。

2. 数据⽂件

⽂件的内容不⼀定是程序,⽽是程序运⾏时读写的数据,⽐如程序运⾏需要从中读取数据的⽂件,或

者输出内容的⽂件。

而对于我们来说,编译好的程序通过之前说过的编译链接过程,就是生成一个执行文件.exe。所以,这里我们重点讨论的是数据文件,即将程序得到的数据写入到文件内部或者直接从数据文件中得到数据进入到内存中进行我们的操作

1.数据文件的分类:

1.文本文件:

文本文件即将得到的数据以字符形式存储起来,无论传入时这个数据是什么类型的:

比如:10000这个数字,以整型的形式被写入文本文件时,文本文件是这样识别的:‘1’ ‘0’ ‘0’‘0’‘0’,也就是以五个字符的形式写入到文件中,而存储的正是他们符号对应的ASCII的数值,且是char类型一字节8比特位存储以二进制形式存储他们的ASCII值。

2.⼆进制⽂件:

顾名思义,即以二进制形式把数据存储到文件中。

3.文件操作的基本格式(文件的打开和关闭):

在学习文件时,我们可以联想我们的动态内存开辟的知识点,他们有很多的相似之处。

首先是文件操作基本的格式,**我们首先清楚,一个程序能打开的文件是有限的,倘若达到了这个临界值,后续是不能打开文件了。**这就要求我们在打开文件后一定要养成及时关闭文件的好习惯。

故我给出了文件使用的基本格式:

int main()
{
   //首先要打开文件:
   FILE*pf=fopen("文件名“,"打开方式”);
   if(pf==NULL)//打开文件后要养成检验文件是否打开成功的好习惯,方式同动态开辟差不多
   {
      perror("fopen failed");
      return 1;
   }
   //使用过程
   //
   //
   fclose(pf);
   pf=NULL;
   return 0;
}

如图我上面所写的程序所示,文件操作最关键的便是文件的打开和关闭,想要操作文件,我们首先一定要使用一个FILE*的指针接收fopen函数。然后在结尾将文件关闭并且将文件指针置空。哦对了,作为一名程序员,一定要在必要的地方给自己留下一些方便调试的程序,在文件操作时,我们也要跟动态开辟内存那里一样写一个检验是否成功的函数,以方便我们后续找错误。

所以,下面让我们首先介绍一下文件操作最基本的两个函数:fopen fclose

1.fopen函数:

由函数的名字,我们便知道它是用来打开文件的函数,其基本格式如下:

FILE * fopen ( const char * filename, const char * mode )它的两个参数,第一个即对应一个你想要打开的文件的名字,第二个参数对应你想要打开的方式(!!!这里一定要注意,这个打开方式的符号要用双引号,而不是单引号,一定要注意!!!!!)

常见的文件打开方式的符号表如下:

我们在这里常用的有r w a rb wb ab。

!!!还是要强调一遍,打开文件的方式一定要用双引号而不是单引号,这个可别再错了!!!!!

2.fclose函数:

即关闭文件操作函数,格式如下:

int fclose ( FILE * stream ),这个参数即我们的FILE*的指针,使用后文件就会关闭,就跟动态开辟函数close一样,这个也是不能自动置空的,所以我们使用完也要人工置空一下。

4.文件操作函数的介绍:

1.文件的读写方式:

文件的读写方式分为两种:第一种为顺序读写,第二种为随机读写

2.文件的顺序读写:

顺序读写,顾名思义,即按照先后顺序依次写入文件或者从文件中读取数据:

首先,我们必须清楚的一个概念是,我们所谓的读取和写入都是针对内存来说,即内存向其写入,内存从中读取数据,这是我们操作文件时必须要清晰的知道的一个概念

其常见的操作函数包括:

1.fgetc fputc函数:

1.fputc函数:

其作用是内存将数据以单个数据依次写入的方式写入文件。**格式为:

int fputc ( int character, FILE * stream )第一个参数即是我们想要写入的东西,可以是字符也可以是数字,但注意,只能是单个字符或者数字,不能是字符串。第二个参数即是我们想要写入文件的文件指针。

2.fgetc函数:

其作用是从文件中以单个数据的方式依次读取数据到内存中.格式为:

int fgetc ( FILE * stream ) 其参数即为对应的文件指针,对于fgetc读取到的数据,我们要用int整型来接收,不管是ASCII形式还是数字形式倘若文件读取不到数据,则返回EOF,故我们也可以这样说,当文件读取到EOF时,标志着文件读取到结尾了

2.fgets fputs函数:

如果把fgetc fputc中的c理解为char字符的话,那么这里的fgets fputs则把s理解为string,即字符串形式,故我们马上得知,他们是用来处理字符串读取的。

1.fputs函数:

将字符串从内存中写入文件.格式为:

int fputs ( const char * str, FILE * stream ),基本参数信息与fputc差不多,就是第一个不再是单引号的字符,而是一个字符串直接写入文件中了。

2.fgets函数:

将文件中的整段数据直接读取到内存中,格式为:

**char * fgets ( char * str, int num, FILE * stream )**三个参数分别为,第一个:要读取接收的字符串,第二个:要读取的个数 第三个:读取的文件指针。

注意一些细节:
1.对于int num它读取的原则是,会给\0留一个位置,比如读取14个数据,最后只能读取13个,那一个位置要留给\0,故我们考虑长度前一定要给\0预留出位置来。
2.倘若文件读取不到数据,则返回NULL,故NULL返回也可以作为文件读取结束的标志 .

3.fsanf fprintf函数:

1.fprintf函数:

即向文件里面写入内存中的数据的函数,格式如下:

**int fprintf ( FILE * stream, const char * format, … ),**参数与printf基本相同,只是在最开头要加上对应的函数指针,表示要写入的文件。

2.fscanf函数:

从文件中读取内容存入到内存的函数,格式如下:

int fscanf ( FILE * stream, const char * format, … ),参数与scanf基本相同,在最开头的参数对应函数指针,表示从哪个文件中读取数据到内存中。

4.fread fwrite函数:

二进制的读取和写入。

1.fwrite函数:

以二进制的形式写入文件中,格式为:

**size_t fread ( void * ptr, size_t size, size_t count, FILE * stream ),**第一个参数为要传入的数据指针(注意,哪怕是单个的数据,传入的也是指针,别记错了),第二个,第三个数据分别为一个参数的大小和要传入的参数的个数,最后一个参数即为对应的文件指针。

经过这样的处理,文件传入的即为二进制形式的数据。

2.fread函数:

即以二进制的形式读取文件中的数据,之后再根据需要转换成相应的读取方式即可。格式如下:

**size_t fread ( void * ptr, size_t size, size_t count, FILE * stream )**第一个参数是将数据读取后放到的数据指针里,第二个,第三个为单个数据大小和要读取参数个数,最后一个即要读取的函数指针(也可以说是要读取的函数的流)

注意:fread返回的读取到的数据个数,可以利用这一点判断文件读取是否结束

3.文件的随机读写:

顺序读写,实质上是由一个指针进行控制,保证每次的位置。而随机读写同样也是如此,但是我们是可以改变这个指针的位置的,所以才会形成**”随机“**这样的说法。

1.fseek函数:

其作用为可以任意改变文件操作的起始位置,其格式如下:

int fseek ( FILE * stream, long int offset, int origin ),第一个参数为文件指针,第二个参数为偏移量,可以向左(即为负数)也可以向右(即为正数),最后一个参数是基准的初始位置,即对应的offset的移动的基准是哪个位置。

常见的origin有三种:也就是说,我们传入的origin基本也就这三种
1.SEEK_CUR 指针的当前位置
2.SEEK_END 从文件的结尾开始
3.SEEK_SET 从文件的开头开始

2.ftell函数:

用来返回文件指针相对于起始位置的偏移量,格式为:

long int ftell ( FILE * stream )

3.rewind函数:

让文件指针的位置回到文件的起始位置,格式为:

void rewind(FILE*stream)

4.文件的结束情况判断:

!!!!!首先必须要强调的一点:feof不是用来判断文件是否结束的!!!!!

文件结束的判断方式有:1.利用fgetc读取到EOF即为结束 2.利用fgets读取到NULL即为结束 3.二进制文件的读取结束的个数判断文件读取是否结束

而我们的feof和ferror是来判断文件结束的原因的,而不是判断文件何时结束的。

1.feof函数:

int feof ( FILE * stream ),判断文件是否以正常读取结束而结束

2.ferror函数:

int ferror ( FILE * stream ),判断文件是否已读取出现错误而结束

一般在使用的时候,都是feof配合ferror一起使用,来查看文件读取到底是以哪种方式结束的

4.文件缓冲区:

ANSIC 标准采⽤“缓冲⽂件系统”处理的数据⽂件的,所谓缓冲⽂件系统是指系统⾃动地在内存中为

程序中每⼀个正在使⽤的⽂件开辟⼀块“⽂件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓

冲区,装满缓冲区后才⼀起送到磁盘上。如果从磁盘向计算机读⼊数据,则从磁盘⽂件中读取数据输

⼊到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓

冲区的⼤⼩根据C编译系统决定的。

5.总结:

以上便是我对文件操作的一些粗浅的理解,掌握了文件,我们实际上就可以做一些真正能存储数据的程序了,虽然很简陋,但是也比存不下来要强很多,希望各位通过这篇文章能够彻底弄懂文件操作。

目录
相关文章
|
2月前
|
安全 C语言
C语言中的字符、字符串及内存操作函数详细讲解
通过这些函数的正确使用,可以有效管理字符串和内存操作,它们是C语言编程中不可或缺的工具。
230 15
|
8月前
|
存储 算法 C语言
【C语言程序设计——函数】素数判定(头歌实践教学平台习题)【合集】
本内容介绍了编写一个判断素数的子函数的任务,涵盖循环控制与跳转语句、算术运算符(%)、以及素数的概念。任务要求在主函数中输入整数并输出是否为素数的信息。相关知识包括 `for` 和 `while` 循环、`break` 和 `continue` 语句、取余运算符 `%` 的使用及素数定义、分布规律和应用场景。编程要求根据提示补充代码,测试说明提供了输入输出示例,最后给出通关代码和测试结果。 任务核心:编写判断素数的子函数并在主函数中调用,涉及循环结构和条件判断。
364 23
|
3月前
|
存储 编译器 程序员
c语言的文件操作与文件缓冲区
如果没有文件,我们写的程序的数据是存储在电脑的内存中,如果程序退出,内存回收,数据就丢失了,等再次运行程序,是看不到上次程序的数据的,如果要将数据进行持久化的保存,我们可以使用文件。磁盘(硬盘)上的文件是文件。但是在程序设计中,我们⼀般谈的⽂件有两种:程序文件、数据文件(从文件功能的角度来分类 的)。就比如说我们电脑中以.txt为后缀的就是文件的一种,他就是数据文件。.exe为后缀的就为程序文件。函数名功能适用范围fgetc字符输入函数所有输入流fputc字符输出函数所有输出流fgets。
95 0
|
7月前
|
人工智能 Java 程序员
一文彻底搞清楚C语言的函数
本文介绍C语言函数:函数是程序模块化的工具,由函数头和函数体组成,涵盖定义、调用、参数传递及声明等内容。值传递确保实参不受影响,函数声明增强代码可读性。君志所向,一往无前!
165 1
一文彻底搞清楚C语言的函数
|
8月前
|
算法 C语言
【C语言程序设计——函数】利用函数求解最大公约数和最小公倍数(头歌实践教学平台习题)【合集】
本文档介绍了如何编写两个子函数,分别求任意两个整数的最大公约数和最小公倍数。内容涵盖循环控制与跳转语句的使用、最大公约数的求法(包括辗转相除法和更相减损术),以及基于最大公约数求最小公倍数的方法。通过示例代码和测试说明,帮助读者理解和实现相关算法。最终提供了完整的通关代码及测试结果,确保编程任务的成功完成。
301 15
【C语言程序设计——函数】利用函数求解最大公约数和最小公倍数(头歌实践教学平台习题)【合集】
|
8月前
|
C语言
【C语言程序设计——函数】亲密数判定(头歌实践教学平台习题)【合集】
本文介绍了通过编程实现打印3000以内的全部亲密数的任务。主要内容包括: 1. **任务描述**:实现函数打印3000以内的全部亲密数。 2. **相关知识**: - 循环控制和跳转语句(for、while循环,break、continue语句)的使用。 - 亲密数的概念及历史背景。 - 判断亲密数的方法:计算数A的因子和存于B,再计算B的因子和存于sum,最后比较sum与A是否相等。 3. **编程要求**:根据提示在指定区域内补充代码。 4. **测试说明**:平台对代码进行测试,预期输出如220和284是一组亲密数。 5. **通关代码**:提供了完整的C语言代码实现
140 24
|
8月前
|
存储 C语言
【C语言程序设计——函数】递归求斐波那契数列的前n项(头歌实践教学平台习题)【合集】
本关任务是编写递归函数求斐波那契数列的前n项。主要内容包括: 1. **递归的概念**:递归是一种函数直接或间接调用自身的编程技巧,通过“俄罗斯套娃”的方式解决问题。 2. **边界条件的确定**:边界条件是递归停止的条件,确保递归不会无限进行。例如,计算阶乘时,当n为0或1时返回1。 3. **循环控制与跳转语句**:介绍`for`、`while`循环及`break`、`continue`语句的使用方法。 编程要求是在右侧编辑器Begin--End之间补充代码,测试输入分别为3和5,预期输出为斐波那契数列的前几项。通关代码已给出,需确保正确实现递归逻辑并处理好边界条件,以避免栈溢出或结果
354 16
|
8月前
|
存储 编译器 C语言
【C语言程序设计——函数】分数数列求和2(头歌实践教学平台习题)【合集】
函数首部:按照 C 语言语法,函数的定义首部表明这是一个自定义函数,函数名为fun,它接收一个整型参数n,用于指定要求阶乘的那个数,并且函数的返回值类型为float(在实际中如果阶乘结果数值较大,用float可能会有精度损失,也可以考虑使用double等更合适的数据类型,这里以float为例)。例如:// 函数体代码将放在这里函数体内部变量定义:在函数体中,首先需要定义一些变量来辅助完成阶乘的计算。比如需要定义一个变量(通常为float或double类型,这里假设用float。
195 3
|
8月前
|
存储 算法 安全
【C语言程序设计——函数】分数数列求和1(头歌实践教学平台习题)【合集】
if 语句是最基础的形式,当条件为真时执行其内部的语句块;switch 语句则适用于针对一个表达式的多个固定值进行判断,根据表达式的值与各个 case 后的常量值匹配情况,执行相应 case 分支下的语句,直到遇到 break 语句跳出 switch 结构,若没有匹配值则执行 default 分支(可选)。例如,在判断一个数是否大于 10 的场景中,条件表达式为 “num> 10”,这里的 “num” 是程序中的变量,通过比较其值与 10 的大小关系来确定条件的真假。常量的值必须是唯一的,且在同一个。
165 2
|
8月前
|
存储 小程序 C语言
【C语言程序设计——文件】文件操作(头歌实践教学平台习题)【合集】
本文介绍了C语言中的文件操作,分为两个关卡。第1关任务是将键盘输入的字符(以#结束)存入`file1.txt`并显示输出;第2关任务是从键盘输入若干行文本(每行不超过80个字符,用-1作为结束标志),写入`file2.txt`后再读取并显示。文中详细讲解了文件的打开、读取(使用`fgetc()`和`fgets()`)、写入(使用`fputc()`和`fputs()`)及关闭操作,并提供了示例代码和测试说明。
228 5