火龙信奥
  • 分享
  • 课程
  • 在线题库
  • CSES
    • GESP
    • CSP
  • 打卡
    • 代码对战
    • 快速对战
  • 题单
  • 知识课堂
  • 在线比赛
  • 团队
  • 荣誉墙
  • 商城
  • 登录 / 注册

四级 -文件重定向与文件读写操作

作者: 作者的头像   huolong , 时间:2026-10-04 11:24:29 , 所有人可见, 阅读  21

CCF GESP C++ 四级考级专项讲义

主题:文件重定向与文件读写操作


一、 考点概述与大纲要求

在CCF GESP C++ 四级考试中,随着题目难度的提升,标准输入输出(cin / cout)往往无法满足大数据量或特定评测环境的需求。掌握文件的输入输出操作是信息学竞赛(OI)选手的必备基本功。

本讲核心知识点: 1. 为什么需要文件操作与重定向? 2. C++ 文件流操作 (ifstream, ofstream, fstream) 3. C 风格文件操作 (fopen, fscanf, fprintf, fclose) —— 作为拓展了解 4. 信息学竞赛中最常用的杀手锏:文件重定向 (freopen) 5. 经典实战例题讲解


二、 为什么需要文件操作?

  • 标准输入输出 (cin/cout):数据从键盘输入,输出到屏幕。缺点是如果数据量很大(比如几万行),手动输入不可能实现;屏幕输出也无法保存。
  • 文件输入输出:程序直接从文件中读取数据,并将结果写入到指定文件中。
  • 信息学竞赛(OI)的要求:绝大多数OJ(Online Judge)系统和考级评测时,都要求选手通过文件来读取输入数据(.in)和输出结果(.out / .ans)。

三、 C++ 风格的文件读写操作

C++ 通过头文件 <fstream> 提供了面向对象的文件操作方式,主要涉及三个类: 1. ifstream:专用于读文件(Input File Stream) 2. ofstream:专用于写文件(Output File Stream) 3. fstream:同时支持读和写

1. 基本步骤

  1. 包含头文件 #include <fstream>
  2. 创建文件流对象,并打开文件
  3. 进行读写操作(使用 >> 和 <<,或者 getline() 等)
  4. 关闭文件 (close())

2. 代码实例:C++ 文件读写

假设当前目录下有一个名为 input.txt 的文件,里面包含两个整数。我们需要读取它们,求和后写入到 output.txt 中。

#include <iostream>
#include <fstream> // 1. 包含头文件

using namespace std;

int main() {
    // 2. 创建输入流对象并打开文件(用于读)
    ifstream inFile("input.txt");

    // 检查文件是否成功打开
    if (!inFile) {
        cerr << "错误:无法打开输入文件!" << endl;
        return 1;
    }

    int a, b;
    // 3. 从文件中读取数据
    inFile >> a >> b;

    // 关闭输入文件
    inFile.close(); 

    int sum = a + b;

    // 2. 创建输出流对象并打开文件(用于写)
    ofstream outFile("output.txt");

    if (!outFile) {
        cerr << "错误:无法打开输出文件!" << endl;
        return 1;
    }

    // 3. 将结果写入文件
    outFile << "两数之和为: " << sum << endl;

    // 4. 关闭输出文件
    outFile.close();

    cout << "文件读写完毕,结果已写入 output.txt" << endl;
    return 0;
}

四、 C 风格的文件读写操作(拓展了解)

在老代码或部分系统编程中,常使用 C 语言的 <cstdio>(即 <stdio.h>)库进行文件操作。GESP考试虽然以 C++ 为主,但了解 C 风格有助于阅读各类参考代码。

核心函数:

  • FILE *fopen(const char *filename, const char *mode); —— 打开文件
  • "r":只读方式打开
  • "w":只写方式打开(会清空原文件内容)
  • "a":追加方式打开
  • int fscanf(FILE *stream, const char *format, ...); —— 格式化读
  • int fprintf(FILE *stream, const char *format, ...); —— 格式化写
  • int fclose(FILE *stream); —— 关闭文件

代码实例:C 风格读写

#include <iostream>
#include <cstdio> // 包含C风格输入输出头文件

using namespace std;

int main() {
    // 1. 打开文件用于读取
    FILE *fin = fopen("input.txt", "r");
    if (fin == NULL) {
        printf("无法打开输入文件\n");
        return 1;
    }

    int a, b;
    // 2. 从文件读取
    fscanf(fin, "%d %d", &a, &b);

    // 3. 关闭文件
    fclose(fin);

    int sum = a + b;

    // 1. 打开文件用于写入
    FILE *fout = fopen("output.txt", "w");
    if (fout == NULL) {
        printf("无法打开输出文件\n");
        return 1;
    }

    // 2. 写入文件
    fprintf(fout, "Sum = %d\n", sum);

    // 3. 关闭文件
    fclose(fout);

    return 0;
}

五、 信息学竞赛杀手锏:文件重定向 (freopen)

在信息学竞赛(如GESP、CSP-J/S)中,如果每一道题都要去写 ifstream、ofstream 并在代码各处修改流对象,会非常繁琐,且容易在考场上出错。

竞赛中最推荐的做法是使用 freopen 进行“文件重定向”。

1. 什么是文件重定向?

freopen 可以把标准输入(stdin,即键盘 cin)和标准输出(stdout,即屏幕 cout)重定向到指定的磁盘文件中。 * 妙处在于:你在代码中完全不需要修改任何 cin 和 cout,就像平时写本地调试代码一样!只需在 main 函数开头加上两行代码,程序就会自动从文件读入,并自动输出到文件。

2. 函数原型与用法

FILE *freopen(const char *filename, const char *mode, FILE *stream);
  • filename:文件名。
  • mode:模式("r" 表示读,"w" 表示写)。
  • stream:通常填 stdin(输入)或 stdout(输出)。

3. 竞赛标准模板代码

#include <iostream>

using namespace std;

int main() {
    // 【核心技巧】文件重定向
    // 把标准输入重定向到 sum.in
    freopen("sum.in", "r", stdin);
    // 把标准输出重定向到 sum.out
    freopen("sum.out", "w", stdout);

    int a, b;
    // 照常使用 cin 读取(实际上是从 sum.in 中读)
    cin >> a >> b;

    // 照常使用 cout 输出(实际上是写入到 sum.out 中)
    cout << a + b << endl;

    // 竞赛中最后一般可以不写 fclose,系统会自动回收,但养成好习惯写上也可以
    return 0;
}

4. 考试调试技巧(调试与提交的切换)

在本地写代码时,我们需要调试,如果加上了 freopen,屏幕上就看不到输入输出了,很不方便。因此,竞赛选手通常会使用 宏定义 来灵活切换:

#include <iostream>

using namespace std;

// 定义一个宏,平时调试时注释掉下面这行,提交时取消注释
#define LOCAL

int main() {
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    int a, b;
    cin >> a >> b;
    cout << "结果是: " << a + b << endl;

    return 0;
}
  • 本地调试:不交 LOCAL,直接在控制台键盘输入,屏幕看结果。
  • 考场提交/评测:加上 #define LOCAL(或者评测系统自动定义),程序无缝切换为读写指定文件。

六、 经典例题实战

题目:A+B 文件版

题目描述: 从文件 aplusb.in 中读入两个正整数 $A$ 和 $B$($1 \le A, B \le 10^9$),计算它们的和,并将结果输出到文件 aplusb.out 中。

C++ 完整解答(使用 freopen):

#include <iostream>

using namespace std;

int main() {
    // 1. 重定向输入输出
    freopen("aplusb.in", "r", stdin);
    freopen("aplusb.out", "w", stdout);

    // 2. 定义变量(注意数据范围,用long long更安全)
    long long a, b;

    // 3. 读取数据
    if (cin >> a >> b) {
        // 4. 输出数据
        cout << a + b << endl;
    }

    return 0;
}

七、 考点总结与注意事项(避坑指南)

  1. 文件名拼写:考场上一定要看清题目要求的输入输出文件名(大小写、后缀名如 .in / .out),文件名拼错直接导致该题不得分(零分!)。
  2. 文件路径:如果不写路径(如 "input.txt"),文件默认保存在源代码同级目录下或编译运行的当前工作目录中。
  3. 文件关闭:使用 ifstream 和 ofstream 时,用完一定要 .close();而用 freopen 重定向的,系统会在程序结束时自动关闭。
  4. 流状态检查:在做复杂文件读写时,养成习惯用 if (!fin.is_open()) 来判断文件是否成功打开,防止因找不到文件而导致程序崩溃。

—— 本文来自火龙信奥(义乌睿码科技):义乌青少年信息学奥赛与编程教育平台,专注 CSP-J/S、NOIP、GESP 竞赛培训,线上线下融合教学,助力编程升学。网址:hlcoding.com

关于火龙

  • 关于我们
  • 学员获奖
  • 预约试听
  • ACM课程
  • CSP课程
  • 学习指南

帮助中心

  • 用户协议
  • 打字练习 HOT
  • 在线画图
  • DevC++下载
  • CSP报名
  • GESP官网

推荐课程

  • C++零基础入门(可试看)
  • C++进阶提升
  • GESP考级辅导
  • GESP打卡
  • CSP-J/S打卡

公众号

火龙信奥公众号二维码

© 2017-2026 义乌市睿码科技有限公司版权所有 浙ICP备2021013995号

火龙信奥
请输入登录信息


请完成安全验证
验证码底图 滑块
向右拖动滑块完成验证
请输入用户名 / 绑定的手机号码



请输入注册信息(手机号验证码注册)





验证码5分钟有效,60秒内不可重复获取,每日最多3次

微信登录

微信登录二维码

正在生成二维码...

账号已过期,请续期。
去续期

绑定手机号

📱

为了更好地保护您的账号安全,享受完整的平台服务

请您尽快绑定手机号码