C语言⽂件操作讲解(1~2)

前言

  本篇文章为C语言⽂件操作讲解(1~2)的总结,涉及的知识点包含了为什么使⽤⽂件、什么是⽂件、⼆进制⽂件和⽂本⽂件、⽂件的打开和关闭、⽂件的顺序读写:fgetc、fputc、fgets、fputs、fscanf、fprintf、fread、fwrite函数等知识的相关内容,   为本章节知识的内容。

一、为什么使用文件

介绍

  我们写的程序数据是存储在电脑的内存中,程序退出后内存会回收数据就丢失了,再次运行无法观察到上一次的数据,而文件是存在硬盘中,即使电脑关机文件也不会丢失,所以我们需要使用文件来将数据进⾏持久化的保存。

二、什么是⽂件

介绍

  磁盘(硬盘)上的⽂件是⽂件, 但是在程序设计中,我们⼀般谈的⽂件有两种:程序⽂件、数据⽂件(从⽂件功能的⻆度来分类的)。

文件的核心特点:

  • 持久性:数据保存在外部存储中,程序退出后不会丢失。
  • 有序性:数据以字节流形式存储,可按顺序或随机访问。
  • 可操控性:支持创建、读取、写入、修改、删除等操作。

1.程序⽂件

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

例:

2.数据⽂件

  ⽂件的内容不⼀定是程序,⽽是程序运⾏时读写的数据,⽐如程序运⾏需要从中读取数据的⽂件,或者输出内容的⽂件。(C语言文件讨论的是数据⽂件)

数据⽂件讲解:

数据文件的核心作用

程序通过数据文件实现数据持久化数据共享

  • 持久化:程序运行时产生的临时数据(如计算结果、用户信息)可写入数据文件,下次运行时直接读取,无需重复生成。
  • 共享性:多个程序可通过读写同一数据文件交换信息(如日志文件、配置文件)。

数据文件的常见类型

  根据存储格式,数据文件可分为两类:

分类存储方式特点典型场景
文本数据文件以ASCII字符编码存储可读性强(可用记事本打开),占用空间较大日志文件(.log)、配置文件(.ini
二进制数据文件按内存中的二进制格式直接存储占用空间小、读写速度快,不可直接阅读图片(.jpg)、数据库文件(.db

三、⼆进制⽂件和⽂本⽂件

介绍

  根据数据的组织形式,数据⽂件被分为⽂本⽂件和⼆进制⽂件(二、中也有介绍)。 数据在内存中以⼆进制的形式存储,如果不加转换的输出到外存的⽂件中,就是⼆进制⽂件。 如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的⽂件就是⽂本⽂件。

  那么⼀个数据在⽂件中是怎么存储的呢?

先给结论:

字符⼀律以ASCII形式存储,数值型数据既可以⽤ASCII形式存储,也可以使⽤⼆进制形式存储。(如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占⽤5个字节(每个字符⼀个字节),⽽ ⼆进制形式输出,则在磁盘上只占4个字节。)

  对: 如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占⽤5个字节(每个字符⼀个字节),⽽ ⼆进制形式输出,则在磁盘上只占4个字节。

图示:

  作图有些糙,见谅,若以⼆进制形式存储,则按内存中的二进制格式直接存储,所以不详细讲解,

讲一下ASCII码的形式存储:

“10000”以ASCII形式存储时,每个字符对应一个ASCII码值,存储为1字节(8位二进制)。具体如下:

字符与ASCII码对应表

字符ASCII码值(十进制)二进制存储形式
'1'4900110001
'0'4800110000
'0'4800110000
'0'4800110000
'0'4800110000

通过这个表,可知列出图的那些值。

总存储大小

“10000”共5个字符,每个字符占1字节,因此总大小为 5字节(5B)。

四、⽂件的打开和关闭

介绍

  1.流和标准流

首先对流讲解:

简单来说:

  我们程序的数据需要输出到各种外部设备,也需要从外部设备获取数据,不同的外部设备的输⼊输出操作各不相同,为了⽅便程序员对各种设备进⾏⽅便的操作,我们抽象出了流的概念,我们可以把流想象成流淌着字符的河。

C程序针对⽂件、画⾯、键盘等的数据输⼊输出操作都是通过流操作的。 ⼀般情况下,我们要想向流⾥写数据,或者从流中读取数据,都是要打开流,然后操作。

标准流:

在C语言中,标准流是程序与外部环境进行输入输出的默认通道,由标准库自动管理,无需手动打开或关闭。

三大标准流及其作用

流名称文件指针功能描述默认设备
标准输入流stdin程序读取外部输入的通道键盘
标准输出流stdout程序输出普通信息的通道显示器(终端窗口)
标准错误流stderr程序输出错误信息的通道显示器(终端窗口)

注意:C语⾔程序在启动的时候,默认打开了这3个流。

核心特点

  1. 自动关联:程序启动时系统自动创建这三个流,可直接通过 stdin/stdout/stderr 指针操作。
  2. 缓冲机制
    • stdout行缓冲(遇到换行符 \n 或缓冲区满时输出)。
    • stderr无缓冲(错误信息立即输出,不等待缓冲)。
    • stdin行缓冲(读取到换行符时结束输入)。
  3. 重定向支持:可通过操作系统命令将流重定向到文件或其他设备(如 ./a.out > output.txt 将 stdout 输出到文件)。

    记:这三个流这是默认打开的,我们使⽤scanf、printf等函数就可以直接进⾏输⼊输出操作的。 stdin、stdout、stderr 三个流的类型是: FILE * ,通常称为⽂件指针。 C语⾔中,就是通过 FILE* 的⽂件指针来维护流的各种操作的。

  2.⽂件指针

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

  在C语言中,文件指针是用于操作文件的核心工具,本质是指向 FILE 结构体的指针,通过它可以访问文件的状态信息(如当前位置、缓冲区、读写模式等)。

声明格式:

FILE* p;       // ⽂件指针变量

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

3.⽂件的打开和关闭函数介绍:

首先:

1.⽂件在读写之前应该先打开⽂件,在使⽤结束之后应该关闭⽂件

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

3.记:规定使⽤ fopen 函数来打开⽂件, fclose 来关闭⽂件。

(1)fopen函数

函数形式:

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

介绍:

功能: fopen 函数是⽤来打开参数后续对流的操作是通过 filename 指定的⽂件,同时将打开的⽂件和⼀个流进⾏关联, fopen 函数返回的指针来维护。具体对流(关联的⽂件)的操作是通过参数 mode 来指定的。

参数:

  1. filename :表⽰被打开的⽂件的名字,这个名字可以绝对路径,也可以是相对路径。
  2. mode :表⽰对打开的⽂件的操作⽅式,具体⻅下⾯的表格。

返回值:

  1. 若⽂件成功打开,该函数将返回⼀个指向FILE 对象的指针,该指针可⽤于后续操作中标识对应的流。
  2. 若打开失败,则返回 NULL 指针,所以⼀定要fopen 的返回值做判断,来验证⽂件是否打开成功。

mode参数:

详略来说:

r文本文件的只读取
w文本文件的只写入
a文本文件的追加(用的少)
rb二进制文件的只读取
wb二进制文件的只写入
ab二进制文件的追加 (用的少)

细说:

  1. r与rb读取的文件,如果不存在,则会报错的。
  2. w与wb写入的文件,如果不存在,则会创建一个该文件名的文件进行写入,但写入的数据会覆盖原来的数据。

代码例子:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE *p=fopen("date.txt","w");

    fclose(p);
}

fclose下面会讲解。

(2)fclose函数

函数形式:

int fclose ( FILE * stream );

介绍:

功能:fclose函数是⽤来关闭参数 stream 关联的⽂件,并取消其关联关系。与该流关联的所有内部缓冲区均会解除关 联并刷新:任何未写⼊的输出缓冲区内容将被写⼊,任何未读取的输⼊缓冲区内容将被丢弃。

参数讲解:

  • stream:指向 FILE 结构体的指针,即需要关闭的文件流(如通过 fopen 打开的文件)。

返回值

  • 成功:返回 0
  • 失败:返回 EOF(通常为 -1),并设置 errno 以指示错误原因(如文件写入错误)。

举例子:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE *p=fopen("date.txt","w");

   int i= fclose(p);
   printf("%d",i);
}

 五、⽂件的顺序读写

介绍

  文件的顺序读写是指按照数据在文件中的物理存储顺序依次读取或写入,是文件操作中最基础的方式。在C语言中,通过 <stdio.h> 库函数实现,常见函数如下:

fgetc从输⼊流中读取⼀个字符所有输入流
fputc从输⼊流中写入⼀个字符所有输出流
fgets从输⼊流中读取⼀个字符串所有输入流
fputs从输⼊流中写入⼀个字符串所有输出流
fscanf从输⼊流中读取带有格式的数据所有输入流
fprintf向输出流中写⼊带有格式的数据所有输出流
fread从输⼊流中读取⼀块数据文件输入流
fwrite向输出流中写⼊⼀块数据文件输出流

  上⾯说的适⽤于所有输⼊流⼀般指适⽤于标准输⼊流和其他输⼊流(如⽂件输⼊流);所有输出流⼀ 般指适⽤于标准输出流和其他输出流(如⽂件输出流)。

常见函数接下来我将一一介绍:

1.fputc函数

函数形式:

int fputc ( int character, FILE * stream );

介绍:

功能:将参数 character 指定的字符写⼊到 stream 指向的输出流中,通常⽤于向⽂件或标准输 出流写⼊字符。在写⼊字符之后,还会调整指⽰器。字符会被写⼊流内部位置指⽰器当前指向的位置,随后该指示器⾃动向前移动⼀个位置。

参数:

character :被写⼊的字符
stream :是⼀个FILE*类型的指针,指向了输出流(通常是⽂件流或stdout)。

返回值:

  1. 成功时返回写⼊的字符(以int形式)。
  2. 失败时返回 EOF (通常是-1),错误会被设置,可通过ferror() 检查具体错误。

(ferror()会在下面讲解的)

代码例:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE *p=fopen("date.txt","w");
    int i=fputc('a',p);
    printf("%d",i);
    fclose(p);
}

对内容的解释:

  1. 打开文件
    FILE *p = fopen("date.txt", "w");

    • 写入模式"w")打开文件date.txt
    • 若文件不存在,则创建新文件;若已存在,则清空原有内容。
  2. 写入字符
    int i = fputc('a', p);

    • 调用fputc向文件流p写入字符'a'
    • 成功时,返回写入的字符'a'(ASCII值为97),并赋值给i
  3. 输出返回值
    printf("%d", i);

    • 在屏幕上打印i的值,即字符'a'的ASCII码97
  4. 关闭文件
    fclose(p);

    • 关闭文件流,释放资源   注意:(必须执行,避免内存泄漏)

运行结果

  • 文件date.txt中会写入单个字符a
  • 屏幕输出97(字符'a'的ASCII值)。

2.fgetc函数

函数形式:

int fgetc ( FILE * stream );

介绍:

功能:从参数 stream 指向的流中读取⼀个字符。函数返回的是⽂件指⽰器当前指向的字符,读取这个字符之后,⽂件指示器将⾃动前进至下⼀个字符。

参数: stream :FILE*类型的⽂件指针,可以是 stdin ,也可以是其他输⼊流的指针。如果是 stdin 就 从标准输⼊流读取数据。如果是⽂件流指针,就从⽂件读取数据。

返回值:

• 成功时返回读取的字符(以 int 形式)。

• 若调⽤时流已处于⽂件末尾,函数返回(feof

  若发⽣读取错误,函数返回 EOF 并设置流的⽂件结束指⽰器( EOF 并设置流的错误指⽰器( ferror )。

(接下来,先说明一下 feof ferror):

feof讲解:

feof 是 C 语言标准库 <stdio.h> 中的一个函数,用于检查文件流是否已到达文件末尾。

函数原型:

int feof(FILE *stream);

返回值:

  • 非零值:文件流已到达末尾或发生读取错误(需结合 ferror 判断具体原因)。
  • 0:文件流未到达末尾。

结合fgetc示例:

(已经提前准备好 date.txt  文件内容:abcdefg)

#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE* p = fopen("date.txt", "r");
    char i;
    while ((i=fgetc(p)) !=EOF)
    {
        printf("%c  ", i);
    }
    if (feof(p))
    {
        printf("\n无错误\n");
    }
    fclose(p);
}

ferror讲解:

ferror 函数是 C 语言中用于检查文件流是否发生错误的标准库函数,定义在 <stdio.h> 中。

函数原型:

int ferror(FILE *stream);

功能说明

  • 作用:判断指定文件流 stream 在上一次的操作中是否发生错误。
  • 返回值
    • 若发生错误:返回非 0 值(通常为 1)。
    • 未发生错误:返回 0

示例:

(没有提前准备好test.txt文件,找不到该文件的)

#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE* file = fopen("test.txt", "r");
    if (file == NULL)
    {
        perror("fopen failed");
        return 1;
    }
    fclose(file);
}

此时可观察到退出代码不为0,可知,出现了错误。

3.fputs函数

函数形式:

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

介绍:

功能将参数 str 指向的字符串写⼊到参数stream指定的流中(不包含结尾的空字符 \0 ),适⽤于⽂件流或标准输出(stdout)。

参数:

  1. str :str是指针,指向了要写⼊的字符串(必须以 \0 结尾)。(注意点)
  2. stream :是⼀个 FILE* 的指针,指向了要写⼊字符串的流。

返回值:

• 成功时返回⾮负整数。

• 失败时返回 EOF (-1),同时会设置流的错误指⽰器,同时可以使⽤ferror() 检查错误原因的。

示例:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE* file = fopen("date.txt", "w");
    if (file == NULL)
    {
        perror("fopen failed");
        return 1;
    }
    fputs("666", file);
    fclose(file);
}

此时打开文件可看见:

注意:

关键注意事项

  1. 不自动添加换行符
    与 puts(自动添加 '\n')不同,fputs 严格写入字符串本身,需手动在 str 中添加 '\n' 实现换行。

  2. 字符串必须以 '\0' 结尾
    若 str 未正确终止,可能导致写入垃圾数据或程序崩溃(未定义行为)。

  3. 错误处理
    若返回 EOF,需通过 ferror(stream) 确认是否为写入错误。

与 puts 的对比:

特性fputs(str, stream)puts(str)
输出目标可指定文件流(如文件、stdout)固定输出到标准输出(stdout)
换行符不自动添加 '\n'自动在字符串后添加 '\n'
返回值成功返回非负值,失败返回 EOF成功返回非负值,失败返回 EOF

4.fgets函数

介绍:

函数形式:

char * fgets ( char * str, int num, FILE * stream );

功能:从 stream 指定输⼊流中读取字符串,⾄读取到换⾏符、⽂件末尾(EOF)或达到指定字符数 (包含结尾的空字符 \0 ),然后将读取到的字符串存储到str指向的空间中。

参数:

• str :是指向字符数组的指针,str指向的空间⽤于存储读取到的字符串。

• num :最⼤读取字符数(包含结尾的 \0 ,实际最多读取 num-1 个字符)。

• stream :输⼊流的⽂件指针(如⽂件流或 stdin )。

返回值:

• 成功时返回 str 指针。

• 若在尝试读取字符时遇到⽂件末尾,则设置⽂件结束指示器,并返回NULL,这需通过 feof()检测出来。

• 若发⽣读取错误,则设置流错误指⽰器,并返回NULL,通过ferror() 即可进行检测。

举例:(已经提前准备好 date.txt  文件内容:666)

#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE* file = fopen("date.txt", "r");
    if (file == NULL)
    {
        perror("fopen failed");
        return 1;
    }
    char a[10];
    fgets(a,9,file);
    puts(a);
    fclose(file);
}

结合例子可知,如果读取的字符数量大于文件中字符串本身的长度的情况下,会将文件中的全部字符读取到字符数组中,并不会报错。

若改文件内容成(abcdefghigklmn),此时:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE* file = fopen("date.txt", "r");
    if (file == NULL)
    {
        perror("fopen failed");
        return 1;
    }
    char a[10];
    fgets(a,9,file);
    puts(a);
    fclose(file);
}

获取了8个字符,剩下的那一个给了'\0' ;

使⽤细节:

  1.  若读取到换⾏符( \n ),会将其包含在字符串中的,以 \0 结尾。
  2. 如果⽂件末尾⽆换⾏符时,字符串以 \0 结尾,不包含 \n 。

5.fprintf函数

介绍:

函数形式:

int fprintf ( FILE * stream, const char * format, ... );

与printf参数值很像,只是本函数中多了参数:文件指针。

功能: fprintf 是将格式化数据写⼊指定⽂件流的函数。它与 printf 类似,但可以输出到任意 ⽂件(如磁盘⽂件、标准输出、标准错误等),⽽不仅限于控制台。

参数:

  1. stream :指向 FILE 对象的指针,表⽰要写⼊的⽂件流(stdout 、⽂件指针等)。
  2. format :格式化字符串,包含要写⼊的⽂本和格式说明符(如 %d 、 %s 等)。
  3. ... :可变参数列表,提供与格式字符串中说明符对应的数据。

返回值:

• 成功时,返回写⼊的字符总数(⾮负值)。

• 失败时,先设置对应流的错误指⽰器,再返回负值,可以通过 ferror() 来检测。

举例:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE* file = fopen("date.txt", "w");
    if (file == NULL)
    {
        perror("fopen failed");
        return 1;
    }
    char a[20] = "abcdefghigklmn";
    fprintf(file, "%s", a);
    fclose(file);
}

而此时:

可知成功了。

也可以通过返回值知晓是否成功:

fprintf函数的返回值能直接反映其执行状态 ✅。当调用成功时,它会返回实际写入的字符数(不包含字符串结束符\0);若失败,则返回负数(通常为EOF,即-1)。

#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE* file = fopen("date.txt", "w");
    if (file == NULL)
    {
        perror("fopen failed");
        return 1;
    }
    char a[20] = "abcdefghigklmn";
    int i=fprintf(file, "%s", a);
    printf("%d",i);
    fclose(file);
}

6.fscanf函数

介绍:

函数形式:

int fscanf ( FILE * stream, const char * format, ... );

与scanf函数参数值很像,本函数中多了参数:文件指针。

功能: fscanf 是从指定⽂件流中读取格式化数据的函数。它类似于 scanf ,但可以指定输⼊源 (如⽂件、标准输⼊等),⽽⾮仅限于控制台输⼊。适⽤于从⽂件解析结构化数据(如整数、浮点 数、字符串等)。

参数:

  1. stream :指向 FILE 对象的指针,表⽰要读取的⽂件流(如 stdin 、⽂件指针等)。
  2. format :格式化字符串,定义如何解析输⼊数据(如 %d 、 %f 、 %s 等)。
  3.  ... :可变参数列表,提供存储数据的变量地址(需与格式字符串中的说明符匹配)。

返回值:

• 成功时,函数返回成功填充到参数列表中的项数。该值可能与预期项数⼀致,也可能因以下原因少于预期(甚⾄为零):

  • 格式和数据匹配失败;
  • 读取发⽣错误;
  •  到达⽂件末尾(EOF)。

• 如果在成功读取任何数据之前发⽣:

  •  发⽣读取错误,会在对应流上设置错误指示符,则返回EOF。
  • 到达⽂件末尾,会在对应流上设置⽂件结束指⽰符,则返回EOF。

举例:(已经提前准备好 date.txt  文件内容:abcdefghigklmn)

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE* file = fopen("date.txt", "r");
    if (file == NULL)
    {
        perror("fopen failed");
        return 1;
    }
    char a[10];
    fscanf(file, "%8s", a);
    puts(a);
    fclose(file);
}

%8s 意思是:取前8个字符,将该字符串存入字符数组a中。

如果读取字符数量超过了数组的上线呢?

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE* file = fopen("date.txt", "r");
    if (file == NULL)
    {
        perror("fopen failed");
        return 1;
    }
    char a[10];
    fscanf(file, "%10s", a);
    puts(a);
    fclose(file);
}

结果:

由代码值:3 可知,代码有问题。

解析:

问题分析:缓冲区存在溢出风险

  •  fscanf 的格式符改为了 %10s,但有个细节:
    char a[10] 的实际容量是10字节,其中最后1字节需要存储字符串结束符 \0
    • %10s 会读取最多10个字符,加上自动添加的 \0,总长度会达到 11字节,超过了 a[10] 的容量,依然会导致 缓冲区溢出
    • 例如:如果文件中字符串是 "1234567890"(10个字符),fscanf 会写入 a[0] 到 a[9],然后在 a[10] 位置添加 \0,但 a 数组只有 a[0]~a[9],越界访问会导致未定义行为(如程序崩溃、数据损坏)。

使用该函数时要注意这些问题。

7. fwrite函数

介绍:

fwrite是 C 语言标准库中用于二进制形式写入数据到文件的函数,位于#include<stdio.h>头文件中。

(fwrite, fread适用于对二进制文件进行操作的情况)

例:⼆进制⽂件"data.bin"

函数形式:

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

功能:函数⽤于将数据块写⼊ stream 指向的⽂件流中,是以2进制的形式写⼊的。

参数讲解:

  • ptr :指向要写⼊的数据块的指针。
  • size :要写⼊的每个数据项的⼤⼩(以字节为单位)。
  • count :要写⼊的数据项的数量。
  • stream :指向 FILE 类型结构体的指针,指定了要写⼊数据的⽂件流。(即表⽰要写⼊的⽂件流(stdout 、⽂件指针等))

返回值:返回实际写⼊的数据项数量。

              如果发⽣错误,则返回值可能⼩于count 。

注意点:

  •  需要包含 头⽂件。
  • 在使⽤ fwrite() 之前,需要确保⽂件已经以⼆进制可写⽅式打开。
  • fwrite() 通常⽤于⼆进制数据的写⼊,如果写⼊⽂本数据,请谨慎处理换⾏符和编码等问题。 (这个注意:fwrite() 通常⽤于⼆进制数据的写⼊)

举例子:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include <string.h> 
#include<stdlib.h>
int main()
{
	char a[30] = "abcdefghijh";
	int i = strlen(a);
	FILE* p = fopen("date.bin", "w");
	if (p == NULL)
	{
		printf("打开失败\n");
		return;
	}
	fwrite(a, sizeof(a[0]), i, p);
	fclose(p);
}

写入结构体:

#include <stdio.h>
#include <string.h>

typedef struct {
    char name[20];
    int age;
    float score;
} Student;

int main() {
    FILE *file = fopen("students.bin", "wb");
    if (file == NULL) { perror("Error"); return 1; }

    Student stu = {"Alice", 20, 95.5f};
    fwrite(&stu, sizeof(Student), 1, file); // 写入整个结构体

    fclose(file);
    return 0;
}

注意:

fwrite 需配合文件打开模式 "wb"(二进制写入),若用 "w"(文本模式),可能导致换行符 \n 被自动转换,破坏二进制数据完整性。

8. fread函数

介绍:

函数形式:

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

功能:函数⽤于从 stream 指向的⽂件流中读取数据块,并将其存储到 ptr 指向的内存缓冲区中。

参数讲解:

• ptr:指向内存区域的指针,⽤于存储从⽂件中读取的数据。

• size:要读取的每个数据块的⼤⼩(以字节为单位)。

• count:要读取的数据块的数量。

• stream:指向FILE类型结构体的指针,指定了要从中读取数据的⽂件流。

返回值:返回实际读取的数据块数量。

记:

  1. 需要包含#include<stdio.h>头⽂件。
  2. 在使⽤ fread() 之前,需要确保⽂件已经以⼆进制可读⽅式打开。(记住fwrite于fread均要求⽂件以⼆进制形式打开)
  3. ptr 指向的内存区域必须⾜够⼤,以便存储指定数量和⼤⼩的数据块。
  4. 如果 fread() 成功读取了指定数量的数据块,则返回值等于count,如果读取数量少于count,则可能已经到达⽂件结尾或者发⽣了错误。
  5. 在⼆进制⽂件读取时,fread是我们常⽤的函数,但对于⽂本⽂件读取,通常使⽤fgets()或fscanf即可。

例子:(设该文件中已经有"Alice", 20, 95.5f 内容了)

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include <string.h> 
#include<stdlib.h>
typedef struct {
    char name[20];
    int age;
    float score;
} Student;
int main() {
    FILE* file = fopen("students.bin", "rb");
    if (file == NULL)
    {
        printf("打开失败\n");
        return;
    }
    Student stu;
    fread(&stu, sizeof(Student), 1, file);
    printf("%s\n", stu.name);
    printf("%d\n", stu.age);
    printf("%f\n", stu.score);
    fclose(file);
    return 0;
}

以此为例。

总结

以上就是今天要讲的内容,本篇文章涉及的C语言⽂件操作讲解的知识点为:为什么使⽤⽂件、什么是⽂件、⼆进制⽂件和⽂本⽂件、⽂件的打开和关闭、⽂件的顺序读写:fgetc、fputc、fgets、fputs、fscanf、fprintf、fread、fwrite函数等知识的相关内容,希望大家能喜欢我的文章,谢谢各位,接下来新的知识内容我会很快更新。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值