<c语言学习>数据文件操作

数据文件

按文件功能讲,计算机的文件分为程序文件 和**数据文件,**数据文件操作以下简称文件操作。

程序文件:

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

数据文件:

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

为什么要用文件操作

  1. 持久化存储数据

    • 文件系统提供了长期保存数据的方法,使得程序在运行结束后产生的数据依然能够保留,并且可以在程序下次运行时读取或更新这些数据。
    • 这对于需要记录用户设置、保存游戏进度、创建数据库、生成日志记录等应用场景至关重要。
  2. 输入/输出功能

    • 文件可用于从外部源读取数据,例如文本文件、图像文件、音频文件等,作为程序的输入。
    • 同样,程序处理的结果也可以写入到文件中,方便进行数据分析、报告生成或其他后续处理。

如何进行文件操作

原本我们写的程序输出一些东西的方式是把数据打印在"黑框框"上,程序结束后,打印的数据没有保存也就不见了:

以下举例为把输出的东西存在一个txt文件里

1.打开文件(引入打开方式,文件指针)

既然我们要输出东西到文件里,那我们首先需要打开一个文件,做好把数据输出到文件的准备,打开的方式如下:

cpp 复制代码
FILE* pf = fopen("data.txt", "w");

这里我们会看到俩个陌生的东西,这里一一解释下:

FILE*(结构体指针):可以理解为文件指针,不过不是直接指向文件,而是指向一个存有文件信息的结构体,这个结构体是编译器自带的,下图为解释:

这个结构体就好像一个管家,有了这个管家的联系方式,就可以实现对文件的操作(告诉管家就行)。

fopen(文件打开函数):我们通过这个函数来打开函数,他会返回管家的地址(FILE*),里面的参数从左到右为1.文件名称(例子中文data.txt) 2.打开方式(例子中为"w",可以理解为写入),确定我们打开这个文件是用来写东西的。后续我们通过这个文件管家指针来操作文件。

2.输出数据给文件(输入流概念)
3.关闭文件

文件有打开也就有关闭,在操作完文件后需要关闭文件,使用函数fclose来关闭文件:这个函数的参数直接是"文件管家"的指针就可以。

cpp 复制代码
fclose(pf);

其他

文件操作还有很多的打开方式,不只是写入(w),还有以下打开方式:

|-----------|----------------------|-----------|
| 文件使用方式 | 含义 | 如果指定文件不存在 |
| "r"(只读) | 为了输入数据,打开一个已经存在的文本文件 | 出错 |
| "w"(只写) | 为了输出数据,打开一个文本文件 | 建立一个新的文件 |
| "a"(追加) | 向文本文件尾添加数据 | 建立一个新的文件 |
| "rb"(只读) | 为了输入数据,打开一个二进制文件 | 出错 |
| "wb"(只写) | 为了输出数据,打开一个二进制文件 | 建立一个新的文件 |
| "ab"(追加) | 向一个二进制文件尾添加数据 | 建立一个新的文件 |
| "r+"(读写) | 为了读和写,打开一个文本文件 | 出错 |
| "w+"(读写) | 为了读和写,建议一个新的文件 | 建立一个新的文件 |
| "a+"(读写) | 打开一个文件,在文件尾进行读写 | 建立一个新的文件 |
| "rb+"(读写) | 为了读和写打开一个二进制文件 | 出错 |
| "wb+"(读写) | 为了读和写,新建一个新的二进制文件 | 建立一个新的文件 |
| "ab+"(读写) | 打开一个二进制文件,在文件尾进行读和写 | 建立一个新的文件 |

文件操作函数也很丰富,包括但不限于:

顺序读写函数:

|---------|---------|-------|
| 功能 | 函数名 | 适用于 |
| 字符输入函数 | fgetc | 所有输入流 |
| 字符输出函数 | fputc | 所有输出流 |
| 文本行输入函数 | fgets | 所有输入流 |
| 文本行输出函数 | fputs | 所有输出流 |
| 格式化输入函数 | fscanf | 所有输入流 |
| 格式化输出函数 | fprintf | 所有输出流 |
| 二进制输入 | fread | 文件 |
| 二进制输出 | fwrite | 文件 |

操作文件的偏移量

可以理解为我们手敲文件的时候的光标,我们通过光标实现在哪里删除字符或增加字符:

改变偏移量(光标)函数举例:
1.int fseek ( FILE * stream, long int offset, int origin );

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

offset:设定偏移量,例如-4代表向左便宜四个字符。

origin: 定位基准点,可以是以下三个宏之一:

1.SEEK_SET 或 0: 基于文件起始位置(即文件首字节)的偏移量。

2.SEEK_CUR 或 1: 基于当前位置的偏移量。

3.SEEK_END 或 2: 基于文件结尾位置的偏移量。

fseek 函数执行成功后,文件流的读写位置会被调整到新的位置,以便后续的读写操作可以从新位置开始。如果 fseek 失败(例如,尝试将位置设置在文件之外的位置),则返回非零值,否则返回0表示成功。

2.long int ftell ( FILE * stream );

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

3.void rewind ( FILE * stream );

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

文件读取结束的判定

int feof(FILE *stream);

feof 函数接受一个指向 FILE 结构体的指针 stream 作为参数,这个结构体通常是由 fopen 函数打开文件后返回的文件指针所指向的。

当调用 feof(stream) 时,函数会检查与 stream 关联的内部文件结束标志(eof flag),如果该标志已经被设置,那么说明之前从该文件流中读取数据时遇到了文件的末尾,函数将返回非零值(通常为1),表示文件结束;反之,如果文件结束标志没有被设置,则返回0,表示还没有达到文件末尾。

需要注意的是,feof 并不能用来确定下一次读取操作是否会成功,因为它只反映过去读取操作的状态。在实际编程中,一般会在尝试读取文件并发生错误(比如 fgetcfgets 返回 EOF)之后,再调用 feof 来确认是否是因为到达了文件尾部而导致的读取失败。同时,在连续读取文件的过程中,正确的做法通常是先尝试读取,然后检查返回值和调用 feof 来确保不会错过文件中的最后一条有效数据。

相关推荐
西岸行者5 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意5 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码5 天前
嵌入式学习路线
学习
毛小茛5 天前
计算机系统概论——校验码
学习
babe小鑫5 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms5 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下5 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。5 天前
2026.2.25监控学习
学习
im_AMBER5 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J5 天前
从“Hello World“ 开始 C++
c语言·c++·学习