当前位置: 首页 > news >正文

C语言基础08——文件的输入与输出

一、文件的基本知识

1.1 文件的定义

        文件(file)一般指存储在外部介质上数据的集合。一批数据是以文件的形式存放在外部介质(如磁盘)上的。操作系统是以文件为单位对数据进行管理的,也就是说,如果想找存放在外部介质上的数据,必须先按文件名找到所指定的文件,然后再从该文件中读取数据。要向外部介质上存储数据也必须先建立一个文件(以文件名作为标志),才能向它输出数据。

1.2 文件的分类

根据数据的组织形式,数据文件可分为文本文件与二进制文件。

(1)文本文件:数据以字符形式存储,每个字符对应 ASCII 码(如整数 123 存储为 '1'、'2'、'3' 三个字符),可被文本编辑器直接读取。

(2)二进制文件:数据按内存中的存储形式直接存储(如整数 123 存储为二进制01111011),节省空间但不可直接被文本编辑器解读。

1.3 文件指针

        C 语言通过文件指针(FILE*类型)操作文件,它指向一个包含文件信息(如文件名、位置指针等)的结构体。例如:

FILE *fp;  // 定义文件指针fp

        为方便起见,通常将这种指向文件信息区的指针变量简称为指向文件的指针变量。

        注意:指向文件的指针变量并不是指向外部介质上的数据文件的开头,而是指向内存中的文件信息区的开头。

二、文件的打开与关闭

        文件操作需遵循 “打开→操作→关闭” 的流程。

2.1 打开文件:fopen 函数

        fopen函数功能:打开指定文件并返回文件指针。

        fopen 函数的调用方式为:

fopen (文件名,使用文件方式);

例如:

fopen ("a1","r");

表示要打开名字为 a1 的文件,使用文件方式为 “读入”(r 代表 read,即读入)。fopen 函数的返回值是指向 a1 文件的指针(即 a1 文件信息区的起始地址)。通常将fopen 函数的返回值赋给一个指向文件的指针变量。如:

FILE *fp; // 定义一个指向文件的指针变量 fp
fp = fopen ("a1","r"); // 将 fopen 函数的返回值赋给指针变量 fp

这样 fp 就和文件 a1 相联系了,或者说,fp 指向了 a1 文件。

可以看出,在打开一个文件时,通知编译系统以下 3 个信息:

(1)需要打开文件的名字,也就是准备访问的文件的名字;

(2)使用文件的方式(“读” 还是 “写” 等);

(3)让哪一个指针变量指向被打开的文件。

示例

FILE *fp = fopen("test.txt", "r");  // 以只读方式打开文本文件
if (fp == NULL) {  // 打开失败时返回NULL,必须判断printf("文件打开失败!");exit(1);  // 退出程序
}

(1)filename:文件名(含路径,如"data.txt""C:\\test.bin")。

(2)mode:打开方式(核心参数)。

        使用文件方式如下表:

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

2.2 关闭文件:fclose () 函数

功能:关闭文件,释放资源,避免数据丢失。

格式:

int fclose(FILE *fp);

返回值:成功返回 0,失败返回 EOF。

示例

fclose(fp);  // 关闭文件
fp = NULL;   // 避免野指针

三、文本文件的读写

        文本文件以字符或字符串为单位读写,常用函数如下:

3.1字符读写:fgetc () 与 fputc ()

fgetc(fp):从fp指向的文件读取一个字符,返回字符 ASCII 值(读到末尾返回 EOF)。

fputc(ch, fp):将字符ch写入fp指向的文件,成功返回该字符,失败返回 EOF。

示例:复制文本文件

FILE *in, *out;
char ch;
in = fopen("source.txt", "r");
out = fopen("dest.txt", "w");
while ((ch = fgetc(in)) != EOF) {  // 读取到末尾时退出fputc(ch, out);  // 写入目标文件
}
fclose(in);
fclose(out);

3.2 字符串读写:fgets () 与 fputs ()

fgets(str, n, fp):从fp读取最多n-1个字符到str,遇到换行或 EOF 停止,自动添加 '\0'。

fputs(str, fp):将字符串str(不含 '\0')写入fp,成功返回非负整数,失败返回 EOF。

示例:读取并显示文本文件内容

char buf[100];
FILE *fp = fopen("test.txt", "r");
while (fgets(buf, 100, fp) != NULL) {  // 读取一行fputs(buf, stdout);  // 输出到屏幕(stdout是标准输出指针)
}
fclose(fp);

3.3 格式化读写:fscanf () 与 fprintf ()

类似scanf()printf(),但操作对象是文件。

fscanf(fp, 格式串, 参数列表):从文件按格式读取数据。

fprintf(fp, 格式串, 参数列表):按格式向文件写入数据。

示例:向文件写入学生信息

FILE *fp = fopen("students.txt", "w");
char name[20] = "张三";
int age = 20;
float score = 90.5;
fprintf(fp, "%s %d %.1f", name, age, score);  // 写入文件
fclose(fp);

四、二进制文件的读写

        二进制文件以数据块为单位读写,常用fread()fwrite()函数。

4.1 fread () 与 fwrite () 函数

格式:

// 从文件读取数据size_t fread(void *ptr, size_t size, size_t count, FILE *fp);// 向文件写入数据size_t fwrite(const void *ptr, size_t size, size_t count, FILE *fp);

ptr:存放数据的内存地址(读时是目标地址,写时是源地址)。

size:每个数据项的字节数(如sizeof(int))。

count:数据项个数。

返回值:成功读写的数据项个数(非字节数)。

4.2 示例:用二进制文件存储结构体数组

struct Student {char name[20];int age;};int main() {struct Student s[2] = {{"张三", 20}, {"李四", 21}};FILE *fp = fopen("stu.bin", "wb");  // 二进制写fwrite(s, sizeof(struct Student), 2, fp);  // 写入2个学生fclose(fp);// 读取二进制文件struct Student read_s[2];fp = fopen("stu.bin", "rb");  // 二进制读fread(read_s, sizeof(struct Student), 2, fp);printf("%s %d\n", read_s[0].name, read_s[0].age);  // 输出:张三 20fclose(fp);return 0;}

五、文件的定位与随机读写

        文件内部有一个位置指针,记录下一次读写的位置。默认情况下,读写操作后位置指针自动后移,也可手动调整实现随机读写。

5.1 ftell ():获取当前位置

        返回位置指针相对于文件开头的字节数,失败返回 - 1L。

long pos = ftell(fp);  // 获取当前位置

5.2 fseek ():移动位置指针

格式:

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

offset:偏移量(正数表示向后移,负数表示向前移)。

origin:起始位置:

SEEK_SET(0):文件开头

SEEK_CUR(1):当前位置

SEEK_END(2):文件末尾

示例:

fseek(fp, 0, SEEK_SET);  // 移到文件开头(等效于rewind(fp))
fseek(fp, 10, SEEK_CUR); // 从当前位置向后移10字节
fseek(fp, -5, SEEK_END); // 从文件末尾向前移5字节

5.3 rewind ():重置位置指针

        将位置指针移到文件开头,等价于fseek(fp, 0, SEEK_SET)。

rewind(fp);  // 指针回到文件开头

六、文件的错误检测

6.1 ferror ():检查文件操作是否出错

若文件操作出错,返回非 0 值;否则返回 0。

if (ferror(fp) != 0) {printf("文件操作错误!");
}

6.2 clearerr ():清除错误标志

        重置文件的错误标志和 EOF 标志,避免影响后续操作。

clearerr(fp);  // 清除错误状态

七、章节核心要点总结

  1. 文件操作的基本流程:打开(fopen)→ 读写 → 关闭(fclose),必须判断文件是否成功打开。
  2. 文本文件与二进制文件的区别:存储形式不同,读写函数不同(文本用fgetc/fprintf等,二进制用fread/fwrite)。
  3. 位置指针:控制读写位置,fseek是随机读写的核心函数。
  4. 安全性:操作完毕必须关闭文件,避免数据丢失或资源泄露。

http://www.lryc.cn/news/622327.html

相关文章:

  • git clone https://gh.llkk.cc/
  • 什么才是真正的白盒测试?
  • 高并发接口性能优化实战:从200ms到20ms的蜕变之路
  • Python正则表达式处理Unicode字符完全指南:从基础到高级实战
  • Python工具箱系列(六十四)
  • Java Lambda表达式是什么,怎么用
  • JavaWeb开发_Day12
  • 研学智得AI-知网推出的AI学术文献阅读工具
  • OpenCV---morphologyEx形态学操作
  • Java中MybatisPlus使用多线程多数据源失效
  • Vue 侦听器(watch 与 watchEffect)全解析3
  • 如何在 FastAPI 中玩转 APScheduler,让任务定时自动执行?
  • 快速了解PCA降维
  • 《Python列表和元组:从入门到花式操作指南》
  • 接口自动化测试步骤
  • Stability AI技术浅析(二):LDM
  • productionSourceMap:true -> 编译的时候不是那么乱码了
  • 详解 k 近邻(KNN)算法:原理、实践与调优 —— 以鸢尾花分类为例
  • C++面试——内存
  • docker重启或系统重启后harbor自动启动
  • MySQL快速恢复数据的N种方案完全教程
  • 口播数字人免费API调用方案
  • MC0439符号统计
  • 【学习笔记】NTP服务客户端配置
  • 9.对象介绍
  • 2025年COR SCI2区,泊位分配、岸桥分配与引航调度的集成规划,深度解析+性能实测
  • 下载及交叉编译zlib库,记录
  • 解决 MySQL 查询速度缓慢的问题
  • 力扣400:第N位数字
  • 【CUDA 编程思想】FusedQKVProj-分组量化矩阵乘法高效实现全流程解析