Skip to content

1.10 文件操作

计算机程序设计 · C语言 · 1.10 文件操作(零基础讲义)

文件操作

🎯 一句话秒杀:文件操作就是"打开→读写→关闭"三步走,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 挂断(否则数据可能没保存就丢了)。

mermaid
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 用于文本。

文件指针

c
FILE *fp;   // FILE是系统定义的结构体类型,fp是文件指针

3.2 打开文件 fopen(2021/2023 必考)

c
FILE *fopen(文件名, 使用方式);
c
FILE *fp = fopen("test.txt", "r");
if (fp == NULL) {          // ⚠️ 必须检查是否打开成功!
    printf("文件打开失败");
    return -1;
}

3.2.1 fopen 失败返回 NULL(2023 真题 加固)

fopen 打开失败时返回 NULL——所以必须 if (fp == NULL) 检查!

什么情况会失败?

  1. "r" 读一个不存在的文件
  2. 文件被占用/无权限
  3. 磁盘错误

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

c
fclose(fp);    // 关闭文件
fp = NULL;     // 指针置空(好习惯)

为什么一定要关闭?

  1. 释放文件指针占用的资源
  2. 刷新缓冲区——确保所有数据真正写入磁盘
  3. 程序能打开的文件数量有限

3.4 文件的读写

3.4.1 函数用途辨析(2022 单选15 必考)

分清"从哪读、往哪写"是本章核心考点!

函数从哪读/往哪写用途
getchar键盘(标准输入)读一个字符
putchar屏幕(标准输出)输出一个字符
fgetc文件从文件读一个字符
fputc文件往文件写一个字符
scanf键盘格式化输入
fscanf文件从文件格式化输入

2022 单选15getchar 从磁盘文件读入字符?→ ——getchar 从标准输入(键盘),不是磁盘文件 陷阱:A"fgets 可从键盘读"是对的(fgets 可读文件也可读键盘 stdin);D"getchar 从磁盘读"是错的

3.4.2 字符读写:fgetc / fputc

c
// 写一个字符
fputc('A', fp);

// 读一个字符
char ch = fgetc(fp);       // 读到文件末尾返回 EOF

3.4.3 字符串读写:fgets / fputs

c
// 写字符串
fputs("Hello", fp);

// 读字符串
char str[100];
fgets(str, 100, fp);       // 读一行(包括换行符),最多读99个字符

3.4.4 格式化读写:fprintf / fscanf

c
// 写入文件
fprintf(fp, "%d %s %.1f", 1001, "张三", 85.5);

// 从文件读取
int id; char name[20]; float score;
fscanf(fp, "%d %s %f", &id, name, &score);

🔑 秒杀秘籍

fprintffscanfprintf/scanf 用法一样——只是多了个 FILE *fp 参数

3.4.5 数据块读写:fread / fwrite(重点!)

c
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);
c
// 将结构体数组写入文件
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 的起始点

c
fseek(fp, 10, SEEK_SET);   // 从文件开头偏移10字节
fseek(fp, -5, SEEK_END);   // 从文件末尾倒退5字节
fseek(fp, 3, SEEK_CUR);    // 从当前位置偏移3字节
起始点常量名
文件开头SEEK_SET0
当前位置SEEK_CUR1
文件末尾SEEK_END2

3.6 完整文件操作示例

c
#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 检测文件末尾

c
// 方式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",并判断是否成功。

c
#include <stdio.h>

int main() {
    FILE *fp = fopen("test.txt", "r");
    if (fp == NULL) {
        printf("文件打开失败\n");
        return -1;
    }
    // 成功,继续操作...
    fclose(fp);
    return 0;
}

逐项推演:

  1. fopen("test.txt", "r"):以只读模式打开
  2. 若文件不存在 → 返回 NULL
  3. if (fp == NULL):检查失败
  4. 成功后用完 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"

逐项分析:

  1. A:无引号,不是字符串常量 ❌
  2. B:无引号 ❌
  3. C:有引号,但 \u 是非法转义、\t 是制表符 ❌
  4. D:双引号 + \\ 表示真正的反斜杠

✅ 答案 D(2021 单选8 原题)。记忆:路径字符串 = 引号 + 每个 \\\

例题 3:2022 真题改编(getchar 用途)

下列说法错误的是(  )

A. fgets 可从键盘读字符串  B. fwrite 输出到文件  C. fputs 输出字符串到文件  D. getchar 从磁盘文件读入字符

逐项分析:

  1. A:fgets 可以读文件也可以读键盘(stdin)→ 对
  2. B:fwrite 往文件写数据块 → 对
  3. C:fputs 往文件写字符串 → 对
  4. D:getchar 从标准输入(键盘)读,不是磁盘文件 → 错

✅ 答案 D(2022 单选15 原题)。记忆:getchar/putchar 管键盘屏幕,fgetc/fputc 管文件

例题 4:2023 真题改编(fopen 返回 NULL)

"r" 模式打开一个不存在的文件,fopen 返回(  )

A. 0  B. NULL  C. 文件指针  D. -1

逐项分析:

  1. "r" 模式要求文件存在
  2. 文件不存在 → 打开失败
  3. 失败时 fopen 返回 NULL
  4. 答案:B. NULL

✅ 对应 2023 真题。记忆:fopen 失败必返回 NULL,写代码必须检查

例题 5:模式判断

想往文件末尾追加内容且不清空原文件,应使用(  )

A. "w"  B. "a"  C. "r"  D. "w+"

逐项分析:

  1. A "w":清空后写入 ❌
  2. B "a":追加到末尾,不清空 ✅
  3. C "r":只读 ❌
  4. D "w+":清空后读写 ❌

✅ 答案 B. "a"。记忆:"a" 追加不清空,"w" 清空重写


⑤ ⚠️【历年真题高频扣分坑】

#陷阱错误做法正确做法出处
1路径转义"c:\user" 直接写每个 \ 写成 \\2021 单选8
2路径不加引号c:\test.txt必须是字符串常量(引号)2021 单选8
3getchar 用途以为 getchar 读文件getchar 读键盘(标准输入)2022 单选15
4fopen 不检查 NULL直接使用 fp失败返回 NULL,必须检查2023
5"w" 清空以为 "w" 不清空"w"/"w+" 清空原内容经典
6"a" 追加以为 "a" 也清空"a" 追加到末尾不清空经典
7fread 用于文本以为 fread 读文本fread/fwrite 用于二进制经典
8fprintf 忘 fp 参数fprintf("%d", x)fprintf(fp, "%d", x) 多 fp经典
9fclose 忘记写完不关闭不关闭可能丢数据经典
10feof 误用用 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) 的作用是什么?
👆 点击展开答案
  1. 文件打开失败(例如文件不存在时用"r"模式打开)

  2. "w" 清空原内容后写入;"a" 保留原内容,在文件末尾追加

  3. 二进制文件(fread/fwrite按数据块读写,速度快)

  4. 将文件位置指针重置到文件开头

  5. 判断是否到达文件末尾(到末尾返回非0)

  6. B. "test.txt"(字符串必须加引号)

  7. 键盘(标准输入)——不是磁盘文件

  8. NULL("r" 要求文件存在)

  9. 文本用 fprintf/fscanf二进制用 fread/fwrite

  10. 关闭文件、刷新缓冲区、释放资源


📖 教材习题对照

教材习题知识点难度
习题10.1~10.2文件打开与关闭⭐⭐
习题10.3~10.4字符读写 fgetc/fputc⭐⭐
习题10.5fprintf/fscanf⭐⭐⭐
习题10.9fread/fwrite数据块读写⭐⭐⭐
习题10.11文件定位 fseek⭐⭐⭐⭐

对应教材:谭浩强《C程序设计》第5版 → 第10章 对文件的输入输出 对应考试大纲:考点10 — 文件操作

📺 配套视频

复习到本考点 → 先看视频补讲,再刷上面「闭卷挑战」。

  • 下位考点 · 抓不到对口免费公开课

仅供个人学习 · 考生回忆版 · 非考试院原卷