文件操作
🎯 一句话秒杀:文件操作就是"打开→读写→关闭"三步走,C语言用
fopen开门、fprintf/fscanf读写、fclose关门。
① 📊【历年真题考情】
本章(文件操作)在广东专升本计算机统考中的位置:
| 项目 | 结论 |
|---|---|
| 出题频次 | ⭐⭐⭐——2026 考纲全解标注"文件操作:单选、判断,约5分,⭐⭐;2/4 年(2023 考)" |
| 常考题型 | 单选(2021 单选8、2022 单选15)、填空(2021 填空33) |
| 预估分值 | 3~10 分 / 200 分(约 2%~5%) |
| 考纲归属 | 2026 考纲「复合数据」考点9(文件打开/关闭/读写) |
考场真实出现过的高频题:
- 2021 单选8:能作为输入文件名的字符串常量 → D.
"c\\user\\text.txt"(双引号+\\转义) - 2021 填空33:打开文件用 fopen
- 2022 单选15:getchar 从磁盘文件读入字符?→ 错(getchar 从标准输入)
- 2023:fopen 失败返回 NULL
🎯 学习目标:学完本章,你能 ① 写出正确的文件路径字符串(含转义);② 分清哪个函数从文件/键盘读写;③ 判断 fopen 各种模式的用途;④ 写出完整的"打开→读写→关闭"程序——这四类题就是本章真题的全部考法。
② 🗣️【零基础大白话引入】
文件操作是什么? 想象你在银行柜台存取档案:
- fopen(打开) = 递上取件单,工作人员把档案从保险柜拿出来(开门)
- fprintf/fread(读写) = 查看或修改档案内容(读写)
- fclose(关闭) = 把档案放回保险柜并锁好(关门)
为什么要"三步走"? 因为文件在磁盘上,而程序在内存里——必须通过 fopen 建立连接(像打电话先拨号),操作完必须 fclose 挂断(否则数据可能没保存就丢了)。
flowchart LR
A["fopen 打开<br/>建立连接<br/>失败返回 NULL(必查!)"] --> B["读写<br/>fprintf/fscanf/fread<br/>fwrite"]
B --> C["fclose 关闭<br/>刷新缓冲区<br/>释放资源"]
style A fill:#2F6B9E,color:#fff
style B fill:#E67E22,color:#fff
style C fill:#C0392B,color:#fff📌 记忆:打开→读写→关闭,三步缺一不可;fopen 失败返回 NULL 必须 if 检查(2023 真题),fclose 忘记可能丢数据。
文件路径为什么那么怪? 在 C 语言里 \ 是转义字符——\n 是换行、\t 是制表符。所以 Windows 路径 c:\user\text.txt 里的 \ 必须写成 \\,否则编译器把 \u、\t 当成特殊字符!
💡 本章主线:文件概念(文本/二进制)→ fopen 打开(重点)→ 读写函数 → fclose 关闭 → 定位。全章就是"记住函数干什么用"——会对比就会做题。
③ 📖【正式核心知识点讲解】
本章知识点 = 考纲要求 + 历年真题实际考过的内容。
3.1 文件的基本概念
文件分类
| 分类方式 | 类型 | 说明 |
|---|---|---|
| 按存储方式 | 文本文件 | ASCII码存储,可读 |
| 二进制文件 | 按内存原样存储,不可直接读 | |
| 按操作方式 | 缓冲文件系统 | 自动在内存开辟缓冲区(标准C) |
| 非缓冲文件系统 | 需程序自行管理缓冲区 |
C语言用的是缓冲文件系统——系统自动在内存中为每个文件开辟缓冲区
💡 文本 vs 二进制:文本文件可读但慢,二进制文件快但不可读。fread/fwrite 用于二进制,fprintf/fscanf 用于文本。
文件指针
FILE *fp; // FILE是系统定义的结构体类型,fp是文件指针3.2 打开文件 fopen(2021/2023 必考)
FILE *fopen(文件名, 使用方式);FILE *fp = fopen("test.txt", "r");
if (fp == NULL) { // ⚠️ 必须检查是否打开成功!
printf("文件打开失败");
return -1;
}3.2.1 fopen 失败返回 NULL(2023 真题 加固)
fopen 打开失败时返回
NULL——所以必须if (fp == NULL)检查!
什么情况会失败?
- 用
"r"读一个不存在的文件 - 文件被占用/无权限
- 磁盘错误
✅ 2023 真题:fopen 失败 → B. NULL 🚨 不检查直接使用 fp 会崩溃(解引用空指针)——这是编程题必扣分点。
3.2.2 文件路径字符串写法(2021 单选8 必考)
文件路径是字符串常量——必须加双引号;Windows 路径中的
\要写成\\
| 写法 | 是否正确 | 原因 |
|---|---|---|
c:user\text.txt | ❌ | 无引号,不是字符串 |
"c\user\text.txt" | ❌ | \u 是非法转义、\t 是制表符 |
"c\\user\\text.txt" | ✅ | \\ 表示一个真正的反斜杠 |
✅ 2021 单选8:能作为输入文件名的字符串常量 → D.
"c\\user\\text.txt"记忆:路径字符串 = 双引号包起来 + 每个\写成\\
文件使用方式
| 模式 | 含义 | 文件不存在时 |
|---|---|---|
"r" | 只读(文本) | 报错 |
"w" | 只写(文本) | 新建 |
"a" | 追加(文本) | 新建 |
"rb" | 只读(二进制) | 报错 |
"wb" | 只写(二进制) | 新建 |
"ab" | 追加(二进制) | 新建 |
"r+" | 读写(文本) | 报错 |
"w+" | 读写(文本) | 新建 |
🚨 红牌警告
"w"和"w+"会清空原有文件内容!文件原来有东西也会被删光"a"追加模式——不会清空文件,写的内容加到末尾 记忆:"r" 要求文件存在(不存在报错);"w"/"a" 不存在就新建
3.3 关闭文件 fclose
fclose(fp); // 关闭文件
fp = NULL; // 指针置空(好习惯)为什么一定要关闭?
- 释放文件指针占用的资源
- 刷新缓冲区——确保所有数据真正写入磁盘
- 程序能打开的文件数量有限
3.4 文件的读写
3.4.1 函数用途辨析(2022 单选15 必考)
分清"从哪读、往哪写"是本章核心考点!
| 函数 | 从哪读/往哪写 | 用途 |
|---|---|---|
getchar | 键盘(标准输入) | 读一个字符 |
putchar | 屏幕(标准输出) | 输出一个字符 |
fgetc | 文件 | 从文件读一个字符 |
fputc | 文件 | 往文件写一个字符 |
scanf | 键盘 | 格式化输入 |
fscanf | 文件 | 从文件格式化输入 |
✅ 2022 单选15:
getchar从磁盘文件读入字符?→ 错——getchar 从标准输入(键盘),不是磁盘文件 陷阱:A"fgets 可从键盘读"是对的(fgets 可读文件也可读键盘 stdin);D"getchar 从磁盘读"是错的
3.4.2 字符读写:fgetc / fputc
// 写一个字符
fputc('A', fp);
// 读一个字符
char ch = fgetc(fp); // 读到文件末尾返回 EOF3.4.3 字符串读写:fgets / fputs
// 写字符串
fputs("Hello", fp);
// 读字符串
char str[100];
fgets(str, 100, fp); // 读一行(包括换行符),最多读99个字符3.4.4 格式化读写:fprintf / fscanf
// 写入文件
fprintf(fp, "%d %s %.1f", 1001, "张三", 85.5);
// 从文件读取
int id; char name[20]; float score;
fscanf(fp, "%d %s %f", &id, name, &score);🔑 秒杀秘籍
fprintf和fscanf和printf/scanf用法一样——只是多了个FILE *fp参数
3.4.5 数据块读写: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);// 将结构体数组写入文件
struct Student stu[3] = {...};
fwrite(stu, sizeof(struct Student), 3, fp);
// 从文件读取回结构体数组
struct Student stu[3];
fread(stu, sizeof(struct Student), 3, fp);🚨 红牌警告
fread/fwrite 用于二进制文件——读写速度快,但不能直接查看内容 fprintf/fscanf 用于文本文件——可读性好,但速度慢
3.5 文件定位
| 函数 | 功能 |
|---|---|
rewind(fp) | 将文件位置指针重置到文件开头 |
fseek(fp, 偏移量, 起始点) | 将位置指针移动到指定位置 |
ftell(fp) | 返回当前指针位置(距文件开头字节数) |
feof(fp) | 判断是否到文件末尾 |
fseek 的起始点
fseek(fp, 10, SEEK_SET); // 从文件开头偏移10字节
fseek(fp, -5, SEEK_END); // 从文件末尾倒退5字节
fseek(fp, 3, SEEK_CUR); // 从当前位置偏移3字节| 起始点 | 常量名 | 值 |
|---|---|---|
| 文件开头 | SEEK_SET | 0 |
| 当前位置 | SEEK_CUR | 1 |
| 文件末尾 | SEEK_END | 2 |
3.6 完整文件操作示例
#include <stdio.h>
#include <stdlib.h>
int main() {
// 1. 打开文件
FILE *fp = fopen("data.txt", "w");
if (fp == NULL) {
printf("打开失败");
exit(1);
}
// 2. 写入数据
fprintf(fp, "Hello, File!\n");
fprintf(fp, "1001 张三 85.5\n");
// 3. 关闭
fclose(fp);
// 4. 重新打开读取
fp = fopen("data.txt", "r");
if (fp == NULL) {
printf("打开失败");
exit(1);
}
// 5. 读取
char str[100];
while (fgets(str, 100, fp) != NULL) {
printf("%s", str);
}
// 6. 关闭
fclose(fp);
return 0;
}3.7 检测文件末尾
// 方式1:feof
while (!feof(fp)) {
// 读数据...
}
// 方式2:fgets(读到末尾返回NULL)
while (fgets(str, 100, fp) != NULL) {
// 处理每一行...
}
// 方式3:fgetc(读到末尾返回EOF)
char ch;
while ((ch = fgetc(fp)) != EOF) {
// 处理每个字符...
}④ 🧪【真题同源例题】
例题 1:入门基础题(先热热身)
用只读模式打开文件 "test.txt",并判断是否成功。
#include <stdio.h>
int main() {
FILE *fp = fopen("test.txt", "r");
if (fp == NULL) {
printf("文件打开失败\n");
return -1;
}
// 成功,继续操作...
fclose(fp);
return 0;
}逐项推演:
fopen("test.txt", "r"):以只读模式打开- 若文件不存在 → 返回 NULL
if (fp == NULL):检查失败- 成功后用完
fclose(fp)关闭
✅ 这是 fopen 的标准三步:打开 → 检查 NULL → 用完关闭
例题 2:2021 真题改编(文件路径转义)
能作为输入文件名的字符串常量是( )
A. c:user\text.txt B. c\user\text.txt C. "c\user\text.txt" D. "c\\user\\text.txt"
逐项分析:
- A:无引号,不是字符串常量 ❌
- B:无引号 ❌
- C:有引号,但
\u是非法转义、\t是制表符 ❌ - D:双引号 +
\\表示真正的反斜杠 ✅
✅ 答案 D(2021 单选8 原题)。记忆:路径字符串 = 引号 + 每个
\变\\
例题 3:2022 真题改编(getchar 用途)
下列说法错误的是( )
A. fgets 可从键盘读字符串 B. fwrite 输出到文件 C. fputs 输出字符串到文件 D. getchar 从磁盘文件读入字符
逐项分析:
- A:fgets 可以读文件也可以读键盘(stdin)→ 对
- B:fwrite 往文件写数据块 → 对
- C:fputs 往文件写字符串 → 对
- D:getchar 从标准输入(键盘)读,不是磁盘文件 → 错
✅ 答案 D(2022 单选15 原题)。记忆:getchar/putchar 管键盘屏幕,fgetc/fputc 管文件
例题 4:2023 真题改编(fopen 返回 NULL)
用 "r" 模式打开一个不存在的文件,fopen 返回( )
A. 0 B. NULL C. 文件指针 D. -1
逐项分析:
"r"模式要求文件存在- 文件不存在 → 打开失败
- 失败时 fopen 返回 NULL
- 答案:B. NULL
✅ 对应 2023 真题。记忆:fopen 失败必返回 NULL,写代码必须检查
例题 5:模式判断
想往文件末尾追加内容且不清空原文件,应使用( )
A. "w" B. "a" C. "r" D. "w+"
逐项分析:
- A "w":清空后写入 ❌
- B "a":追加到末尾,不清空 ✅
- C "r":只读 ❌
- D "w+":清空后读写 ❌
✅ 答案 B. "a"。记忆:"a" 追加不清空,"w" 清空重写
⑤ ⚠️【历年真题高频扣分坑】
| # | 陷阱 | 错误做法 | 正确做法 | 出处 |
|---|---|---|---|---|
| 1 | 路径转义 | "c:\user" 直接写 | 每个 \ 写成 \\ | 2021 单选8 |
| 2 | 路径不加引号 | c:\test.txt | 必须是字符串常量(引号) | 2021 单选8 |
| 3 | getchar 用途 | 以为 getchar 读文件 | getchar 读键盘(标准输入) | 2022 单选15 |
| 4 | fopen 不检查 NULL | 直接使用 fp | 失败返回 NULL,必须检查 | 2023 |
| 5 | "w" 清空 | 以为 "w" 不清空 | "w"/"w+" 清空原内容 | 经典 |
| 6 | "a" 追加 | 以为 "a" 也清空 | "a" 追加到末尾不清空 | 经典 |
| 7 | fread 用于文本 | 以为 fread 读文本 | fread/fwrite 用于二进制 | 经典 |
| 8 | fprintf 忘 fp 参数 | fprintf("%d", x) | fprintf(fp, "%d", x) 多 fp | 经典 |
| 9 | fclose 忘记 | 写完不关闭 | 不关闭可能丢数据 | 经典 |
| 10 | feof 误用 | 用 feof 判断"读到末尾再读" | feof 在读取之后判断 | 经典 |
📌 最值钱的一条:第 1、2 条(路径转义)是 2021 单选8 的核心——"双引号 +
\\转义" 是文件操作第一易错点;第 3 条(getchar)是 2022 单选15。
⑥ 📝【课后自测练习题】
1. 能作为输入文件名的字符串常量是( )(2021 真题风格)
A. d:\data.txt B. "d:\data.txt" C. "d:\\data.txt" D. d:\\data.txt
2. 用 "r" 模式打开不存在的文件,fopen 返回( )(2023 真题风格)
A. 0 B. NULL C. 文件指针 D. -1
3. 下列说法错误的是( )(2022 真题风格)
A. fgets 可从键盘读字符串 B. fwrite 输出到文件 C. fputs 输出字符串到文件 D. getchar 从磁盘文件读入字符
4. 想保留原文件内容并在末尾追加,应使用( )(经典)
A. "w" B. "r" C. "a" D. "w+"
5. 判断:fread/fwrite 通常用于文本文件。( )(经典)
A. 正确 B. 错误
👆 点击展开参考答案与解析
第1题:C. "d:\\data.txt"
- 字符串必须加引号;
\要写成\\(2021 单选8 同款)
第2题:B. NULL
- fopen 失败返回 NULL(2023 真题)
第3题:D. getchar 从磁盘文件读入字符
- getchar 从标准输入(键盘),不是磁盘文件(2022 单选15 原题)
第4题:C. "a"
- "a" 追加到末尾不清空;"w" 清空重写
第5题:B. 错误
- fread/fwrite 用于二进制文件;文本文件用 fprintf/fscanf
📝 原有闭卷真题挑战(保留原内容 + 扩充至 10 题)
(点击下方空白查看答案)
1. fopen返回NULL表示什么?
2. "w" 和 "a" 模式的区别?
3. fread和fwrite通常用于什么类型的文件?
4. rewind(fp) 的作用?
5. feof(fp) 的作用?(扩充题)
6. 能作为文件名的字符串常量是? A. test.txt B. "test.txt" C. 'test.txt'
7. getchar 从哪读取字符?
8. "r" 模式打开不存在的文件返回?
9. 文本文件和二进制文件分别用什么函数读写?
10. fclose(fp) 的作用是什么?👆 点击展开答案
文件打开失败(例如文件不存在时用"r"模式打开)
"w" 清空原内容后写入;"a" 保留原内容,在文件末尾追加
二进制文件(fread/fwrite按数据块读写,速度快)
将文件位置指针重置到文件开头
判断是否到达文件末尾(到末尾返回非0)
B. "test.txt"(字符串必须加引号)
键盘(标准输入)——不是磁盘文件
NULL("r" 要求文件存在)
文本用 fprintf/fscanf;二进制用 fread/fwrite
关闭文件、刷新缓冲区、释放资源
📖 教材习题对照
| 教材习题 | 知识点 | 难度 |
|---|---|---|
| 习题10.1~10.2 | 文件打开与关闭 | ⭐⭐ |
| 习题10.3~10.4 | 字符读写 fgetc/fputc | ⭐⭐ |
| 习题10.5 | fprintf/fscanf | ⭐⭐⭐ |
| 习题10.9 | fread/fwrite数据块读写 | ⭐⭐⭐ |
| 习题10.11 | 文件定位 fseek | ⭐⭐⭐⭐ |
对应教材:谭浩强《C程序设计》第5版 → 第10章 对文件的输入输出 对应考试大纲:考点10 — 文件操作
📺 配套视频
复习到本考点 → 先看视频补讲,再刷上面「闭卷挑战」。
- 下位考点 · 抓不到对口免费公开课