• C++
  • GESP四级|文件重定向与文件读写 零基础竞赛教程

  • @ 2026-7-31 20:52:57

GESP四级|文件重定向与文件读写 零基础竞赛教程

前置说明

文件读写、文件重定向属于 GESP C++四级考点,信奥竞赛必备实用技能。

基础概念 控制台读写:cincout,键盘输入、屏幕输出; 文件读写:从txt文件读取数据,把结果保存到txt; 文件重定向:不用改动cin/cout代码,直接把控制台数据流切换到文件。

所需头文件

#include <iostream>   // cin cout
#include <fstream>    // 文件流 ifstream ofstream
#include <cstdio>    // freopen 文件重定向
using namespace std;

一、文件重定向(freopen,竞赛最常用)

通俗原理

freopen 修改标准输入输出通道。 原本cin读键盘,改成直接读取文件;cout打印屏幕,改成写入文件。 ✅优势:原来写好的cin/cout代码几乎不用修改,一键切换文件读写,比赛调试首选。

函数格式

freopen("输入文件名.txt","r",stdin);  // r = read 读文件
freopen("输出文件名.txt","w",stdout); // w = write 写文件
fclose(stdin);   // 关闭输入通道
fclose(stdout);  // 关闭输出通道

完整带注释示例

#include <iostream>
#include <cstdio>   // freopen头文件
using namespace std;

int main()
{
    // 将标准输入重定向到in.txt,读取文件内容
    freopen("in.txt", "r", stdin);
    // 将标准输出重定向到out.txt,结果写入文件
    freopen("out.txt", "w", stdout);

    int a, b;
    // 依然使用cin,但是数据不再来自键盘,而是in.txt
    cin >> a >> b;
    // 依然使用cout,内容不会打印屏幕,存入out.txt
    cout << a + b << endl;

    // 一定要关闭重定向通道(规范写法,竞赛建议写上)
    fclose(stdin);
    fclose(stdout);
    return 0;
}

使用步骤

  1. 同目录新建 in.txt,里面写入两个数字,例如 10 20
  2. 运行程序,程序自动读取,计算,结果保存到out.txt

⚠考场易错点

  1. "w"模式会清空文件原有全部内容;
  2. 文件路径:程序和txt放在同一个文件夹,直接写文件名;
  3. Windows注意文件名不要写错,区分大小写;
  4. 调试结束想要恢复键盘屏幕输入输出,需要关闭重定向。

二、文件流读写(ifstream / ofstream)

通俗区分

ifstream:文件输入流 → 读文件(相当于文件版cin) ofstream:文件输出流 → 写文件(相当于文件版cout)

写法1:分开读写(常用模板)

#include <iostream>
#include <fstream>  // 文件流必须头文件
using namespace std;

int main()
{
    // 创建读文件对象,打开in.txt
    ifstream fin("in.txt");
    // 创建写文件对象,打开out.txt
    ofstream fout("out.txt");

    // 判断文件是否成功打开(防止文件不存在报错)
    if (!fin.is_open())
    {
        cout << "无法打开输入文件!" << endl;
        return 0;
    }
    if (!fout.is_open())
    {
        cout << "无法打开输出文件!" << endl;
        return 0;
    }

    int a, b;
    fin >> a >> b;        // fin替代cin,读取文件
    fout << a * b << endl;// fout替代cout,写入文件

    // 关闭文件,释放资源
    fin.close();
    fout.close();
    return 0;
}

写法2:fstream 同时支持读写(拓展了解)

#include <iostream>
#include <fstream>
using namespace std;

int main()
{
    // ios::in读,ios::out写
    fstream file("data.txt", ios::in | ios::out);
    int x;
    file >> x;
    file << x + 100;
    file.close();
    return 0;
}

三、两种方案对比(选择题考点)

  1. freopen 文件重定向 ✅优点:原有cin/cout代码无需改动,调试方便,竞赛广泛使用 ❌缺点:全局修改数据流,整个程序所有cin都会读取文件

  2. ifstream / ofstream 文件流 ✅优点:可以同时控制多个文件,灵活区分控制台和文件输出 ❌缺点:代码需要把cin改成fin、cout改成fout,需要修改原有代码

四、读取多行、字符、字符串示例(四级常考)

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main()
{
    ifstream fin("in.txt");
    ofstream fout("out.txt");
    string s;

    // 逐行读取文件所有内容
    while (getline(fin, s))
    {
        fout << "一行内容:" << s << endl;
    }

    fin.close();
    fout.close();
    return 0;
}

注意:cin >> 遇到空格自动截断;getline 读取一整行,包含空格。

五、GESP四级考场避坑清单

  1. 头文件不要漏:freopen需要<cstdio>,文件流需要<fstream>
  2. 打开文件后建议判断is_open(),防止找不到文件程序异常;
  3. "w"写入模式:每次打开清空旧内容;追加内容使用"a"(freopen)/ios::app(文件流);
  4. 程序结束尽量调用close()关闭文件;
  5. 文件名字符串使用英文双引号,不要用中文引号;
  6. 路径问题:程序和txt放在同一文件夹最简单,不要写复杂中文路径。

六、追加:文件追加写入示例

需求:不删除原有内容,在文件末尾新增文字

#include <iostream>
#include <fstream>
using namespace std;

int main()
{
    // ios::app append 追加模式
    ofstream fout("out.txt", ios::app);
    fout << "新增一行文字" << endl;
    fout.close();
    return 0;
}

freopen追加写法:

freopen("out.txt", "a", stdout);

竞赛使用建议

平时刷题调试优先使用 freopen重定向; 如果题目要求同时读取多个文件、同时屏幕+文件输出,使用 ifstream/ofstream 文件流。

2 条评论

  • @ 2026-7-31 20:55:49

    C++ 文件读写 零基础通俗易懂教程

    目标:0基础能看懂、复制代码直接运行、每行带注释 使用 C++ 标准库 <fstream>(文件流,最通用、推荐写法) 三大核心类:

    1. ifstream:读文件(input file stream)
    2. ofstream:写文件(output file stream)
    3. fstream:既能读又能写

    前置知识:基础变量、cout、cin;不懂也没关系,跟着注释理解

    一、头文件必须写

    #include <iostream>   // 控制台输入输出
    #include <fstream>    // 文件读写核心头文件!必不可少
    #include <string>     // 使用字符串string存放文字
    using namespace std;  // 零基础简化写法,不用重复写std::
    

    案例1:写入文件(新建/覆盖文件)

    功能:创建文本文件,写入文字 ⚠️注意:ofstream 默认打开文件会清空原有全部内容

    #include <iostream>
    #include <fstream>
    #include <string>
    using namespace std;
    
    int main()
    {
        // 1. 创建文件输出流对象 out
        ofstream out;
    
        // 2. 打开文件:文件名"test.txt"
        // 如果不存在test.txt → 自动新建
        // 如果已经存在 → 默认清空里面所有内容!
        out.open("test.txt");
    
        // ✅非常重要:判断文件是否成功打开
        // 打不开常见原因:权限不足、路径错误、文件被别的软件占用
        if (!out.is_open())
        {
            cout << "文件打开失败!" << endl;
            return 1; // 异常退出程序
        }
    
        // 3. 向文件写入内容,用法和cout几乎一模一样!
        out << "第一行文字" << endl;
        out << "数字:" << 666 << endl;
        out << "小数:" << 3.14 << endl;
    
        // 4. 关闭文件!好习惯,释放资源
        out.close();
    
        cout << "写入完成!" << endl;
        return 0;
    }
    

    运行后程序同目录生成 test.txt

    案例2:追加写入(不删除原有内容,在末尾添加)

    默认ofstream会覆盖,加参数 ios::app = append 追加模式

    #include <iostream>
    #include <fstream>
    #include <string>
    using namespace std;
    
    int main()
    {
        // ios::app 追加模式
        ofstream out("test.txt", ios::app);
    
        if (!out.is_open())
        {
            cout << "打开失败" << endl;
            return 1;
        }
    
        // 在文件最后新增一行
        out << "【追加的新内容】" << endl;
    
        out.close();
        cout << "追加成功" << endl;
        return 0;
    }
    

    案例3:读取文件(整行读取,最常用)

    ifstream = 读取文件 getline(流对象, 字符串变量):读取一整行文字(包含空格)

    #include <iostream>
    #include <fstream>
    #include <string>
    using namespace std;
    
    int main()
    {
        // 创建文件读取流,打开test.txt
        ifstream in("test.txt");
    
        if (!in.is_open())
        {
            cout << "文件不存在或者打开失败!" << endl;
            return 1;
        }
    
        string line;  // 用来存放读到的每一行文本
    
        // 循环:不断读取一行,读到文件末尾自动停止
        while (getline(in, line))
        {
            // line 就是当前读到的一整行
            cout << line << endl;
        }
    
        in.close(); // 关闭文件
        return 0;
    }
    

    案例4:按单词读取(自动跳过空格、换行)

    直接使用 >> 读取,会自动分隔空格/换行,适合读取数字、单个词语

    #include <iostream>
    #include <fstream>
    #include <string>
    using namespace std;
    
    int main()
    {
        ifstream in("test.txt");
        if (!in)
        {
            cout << "打开失败" << endl;
            return 1;
        }
    
        string word;
        // 一个一个读取单词
        while (in >> word)
        {
            cout << "读到单词:" << word << endl;
        }
    
        in.close();
        return 0;
    }
    

    案例5:同时读写文件 fstream(拓展)

    打开模式组合:ios::in | ios::out

    注意:这种方式不会自动新建文件!文件必须提前存在

    #include <iostream>
    #include <fstream>
    #include <string>
    using namespace std;
    
    int main()
    {
        // 可读可写
        fstream fs("test.txt", ios::in | ios::out);
        if (!fs.is_open())
        {
            cout << "文件不存在!" << endl;
            return 1;
        }
    
        // 先写入一行
        fs << "同时读写测试" << endl;
    
        // ★重要:写完之后需要移动读写指针到文件开头,否则读不到内容
        fs.seekg(0);
    
        string str;
        getline(fs, str);
        cout << str << endl;
    
        fs.close();
        return 0;
    }
    

    二、绝对新手必看关键知识点

    1. 文件路径两种写法

    ① 相对路径(推荐,上面代码用的)

    "test.txt" → 和exe程序放在同一个文件夹

    ② 绝对路径(完整地址)

    Windows系统注意:路径里 \ 在C++字符串必须写成 \\

    // 正确写法
    ifstream in("C:\\Users\\admin\\Desktop\\test.txt");
    

    2. 打开模式参数汇总

    参数 作用
    ios::in 读文件
    ios::out 写文件(默认清空)
    ios::app 追加写入,不清空
    ios::trunc 打开直接清空内容(ofstream默认)
    ios::binary 二进制读写(图片、视频、exe要用)

    3. 常见踩坑清单(新手90%出错点)

    1. 忘记加头文件 #include → 直接报错
    2. 文件路径斜杠只写单个 \ → 编译报错
    3. 忘记判断 is_open(),文件找不到程序直接异常
    4. ofstream 忘记覆盖问题,不小心清空重要文档
    5. 使用 >> 读取文本:遇到空格就截断,不能读取完整一行
    6. 同时读写时,读写指针位置混乱,读不到内容

    三、拓展:二进制文件读写(图片/视频)

    文本文件只能存文字;二进制用来处理图片、音频等。 简单示例:

    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int main()
    {
        // 二进制读取图片
        ifstream in("src.jpg", ios::in | ios::binary);
        ofstream out("copy.jpg", ios::out | ios::binary);
    
        if (!in || !out)
        {
            cout << "打开失败" << endl;
            return 1;
        }
    
        char ch;
        while (in.get(ch))
        {
            out.put(ch);
        }
    
        in.close();
        out.close();
        cout << "图片复制完成" << endl;
        return 0;
    }
    

    四、练习任务(巩固)

    1. 程序输入你的名字和年龄,保存到 info.txt
    2. 读取 info.txt,打印在控制台
    3. 在文件末尾追加一行:记录当前时间
    • @ 2026-7-31 20:54:16

      C++ 文件读写 & 文件重定向 零基础完整教程

      适用:GESP、信奥竞赛(做题最常用)

      前置说明

      C++ 文件操作核心两套方案:

      1. 文件重定向(最简!竞赛刷题首选)freopen,不用改动cin/cout代码
      2. 文件流读写(标准文件操作)ifstream / ofstream,工程通用

      ⚠️ 重要常识

      • 输入文件:读数据 → .in
      • 输出文件:写答案 → .out
      • 文件路径:分相对路径绝对路径,新手优先用相对路径

      一、文件重定向 freopen【竞赛首选,最简单】

      原理:把系统标准输入cin、标准输出cout“转接”到磁盘文件。 你原来写的 cin >> x; cout << x; 一行不用改

      函数原型

      // 读文件:r = read
      freopen("文件名.in","r",stdin);
      // 写文件:w = write,覆盖原有内容
      freopen("文件名.out","w",stdout);
      // 关闭文件
      fclose(stdin);
      fclose(stdout);
      

      头文件必须引入:#include <cstdio>

      完整示例代码

      #include <iostream>
      #include <cstdio>   // freopen、fclose需要这个头文件
      using namespace std;
      
      int main()
      {
          // ========== 文件重定向 ==========
          // 从 data.in 文件读取输入
          freopen("data.in", "r", stdin);
          // 将程序输出写入 data.out
          freopen("data.out", "w", stdout);
      
          // ===== 下面代码和普通cin/cout写法完全一样!=====
          int a,b;
          cin >> a >> b;
          cout << a + b << endl;
          cout << a * b << endl;
      
          // ========= 关闭文件(好习惯,竞赛可省略,但建议写上)=========
          fclose(stdin);
          fclose(stdout);
          return 0;
      }
      

      使用步骤(新手必看)

      1. cpp程序、data.in 放在同一个文件夹
      2. data.in里面写入数据,例如:
      10 20
      
      1. 运行程序,程序不会弹出控制台等待输入,自动读取文件,结果存入data.out 打开data.out会看到:
      30
      200
      

      重点参数讲解

      1. "r" read:只读;文件不存在程序出错
      2. "w" write:只写;文件不存在自动创建;文件已有内容会全部清空覆盖!
      3. "a" append:追加写入,不会清空旧内容,从末尾继续添加(很少用于竞赛)

      ❌ 常见坑

      1. 文件名写错、后缀漏写 data.in 不要写成 data
      2. 文件不在同一个文件夹,找不到文件
      3. 代码调试时忘记注释freopen!运行程序黑屏,以为卡住(程序等待读取文件)

      调试小技巧:做题测试时想切回控制台输入输出,直接注释两行freopen!

      //freopen("data.in","r",stdin);
      //freopen("data.out","w",stdout);
      

      拓展:绝对路径写法(Windows)

      文件放在 D:\test\data.in

      // Windows 路径必须使用双反斜杠 \\
      freopen("D:\\test\\data.in","r",stdin);
      

      二、文件流读写 ifstream / ofstream(C++标准流)

      头文件:#include <fstream>

      • ifstream input file stream:文件读取(相当于文件版cin)
      • ofstream output file stream:文件写入(相当于文件版cout)

      示例1:读取文件 + 写入文件

      #include <iostream>
      #include <fstream>  // 文件流必备头文件
      using namespace std;
      
      int main()
      {
          // 1. 创建文件读取对象,打开data.in
          ifstream fin("data.in");
          // 2. 创建文件写入对象,打开data.out
          ofstream fout("data.out");
      
          // 判断文件是否成功打开(防错)
          if (!fin.is_open())
          {
              cout << "输入文件打开失败!" << endl;
              return 1;
          }
          if (!fout.is_open())
          {
              cout << "输出文件打开失败!" << endl;
              return 1;
          }
      
          // fin 等价于文件内的cin,fout等价于文件内的cout
          int x,y;
          fin >> x >> y;
          fout << x - y << endl;
          fout << x + y << endl;
      
          // 关闭文件,释放资源
          fin.close();
          fout.close();
          return 0;
      }
      

      示例2:逐行读取字符串(getline)

      #include <iostream>
      #include <fstream>
      #include <string>
      using namespace std;
      
      int main()
      {
          ifstream fin("text.in");
          ofstream fout("text.out");
          string s;
      
          // 循环读取一整行,直到文件末尾
          while(getline(fin, s))
          {
              fout << "读到一行:" << s << endl;
          }
      
          fin.close();
          fout.close();
          return 0;
      }
      

      文件结束判断

      文件读到末尾时,流会变为false,两种写法:

      int num;
      //写法1
      while(fin >> num)
      {
          cout << num;
      }
      

      三、两种方案对比(做题怎么选)

      方式 优点 缺点 适用场景
      freopen重定向 代码极少,原有cin/cout直接复用 C语言风格 GESP/信奥竞赛首选
      ifstream/ofstream 面向对象,逻辑清晰,可控性强 需要替换cin→fin,cout→fout 课程作业、正式项目

      ✅竞赛建议:统一使用 freopen!

      四、二进制读写(拓展,GESP基本不考)

      上面全部是文本文件读写(肉眼能看懂) 二进制读写:存储原始字节,一般图像、压缩包使用,了解即可

      // 文件打开增加参数 ios::binary
      ifstream fin("a.dat", ios::binary);
      ofstream fout("b.dat", ios::binary);
      

      📌 高频踩坑清单

      1. 头文件不要漏 freopen → #include<cstdio> ifstream → #include<fstream>
      2. Windows路径单斜杠 \ 会报错,必须写成 \\
      3. "w" 模式打开文件会清空原有内容!不要误操作
      4. 使用getline与 >> 混用注意换行残留问题(新手前期尽量不要混写)
      5. 运行程序提示打不开文件:检查文件名、存放位置

      五、标准竞赛万能模板(直接背诵)

      #include <iostream>
      #include <cstdio>
      using namespace std;
      
      int main()
      {
      #ifdef ONLINE_JUDGE
          // OJ平台自动启用文件读写;本地调试失效
          freopen("input.in","r",stdin);
          freopen("output.out","w",stdout);
      #endif
      
          // 你的解题代码
          int a,b;
          cin>>a>>b;
          cout<<a+b;
      
          fclose(stdin);
          fclose(stdout);
          return 0;
      }
      

      #ifdef ONLINE_JUDGE 妙用:本地电脑调试自动跳过freopen,提交OJ自动开启,不用反复注释!

      • 1