<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 来确保不会错过文件中的最后一条有效数据。

相关推荐
恰薯条的屑海鸥2 小时前
零基础在实践中学习网络安全-皮卡丘靶场(第十六期-SSRF模块)
数据库·学习·安全·web安全·渗透测试·网络安全学习
喜欢吃燃面2 小时前
C++刷题:日期模拟(1)
c++·学习·算法
2301_797604244 小时前
学习记录:DAY32
学习
蓝婷儿4 小时前
6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础
开发语言·python·学习
叶子2024224 小时前
学习使用YOLO的predict函数使用
人工智能·学习·yolo
jackson凌4 小时前
【Java学习笔记】SringBuffer类(重点)
java·笔记·学习
黑客老李6 小时前
JavaSec | SpringAOP 链学习分析
java·运维·服务器·开发语言·学习·apache·memcached
海的诗篇_6 小时前
移除元素-JavaScript【算法学习day.04】
javascript·学习·算法
傍晚冰川7 小时前
FreeRTOS任务调度过程vTaskStartScheduler()&任务设计和划分
开发语言·笔记·stm32·单片机·嵌入式硬件·学习
月初,8 小时前
MongoDB学习和应用(高效的非关系型数据库)
学习·mongodb·nosql