文件操作与异常处理

一句话目标:让程序能从文件读数据、把结果写进文件;并初步认识异常处理这套出错应对机制。

时间复杂度部分见 06.效率-时间复杂度,这里不重复。


第一部分:为什么需要文件操作

程序默认从键盘读、往屏幕写,运行结束数据就没了。
文件操作让我们把数据存到硬盘,下次运行还能读回来 —— 持久保存。

竞赛里也常要求从指定文件读入、写入指定文件


第二部分:C++ 文件流(fstream)

头文件 #include <fstream>,三种流:

类型作用
ifstream输入文件流(文件)
ofstream输出文件流(文件)
fstream可读可写

写文件

#include <fstream>
using namespace std;
 
ofstream fout("out.txt");   // 打开(没有就新建)
fout << "Hello" << endl;
fout << 42 << endl;
fout.close();               // 用完关闭

读文件

ifstream fin("in.txt");
int x;
fin >> x;                   // 用法和 cin 一样
fin.close();

用法和 cin / cout 几乎一样,只是把 cin/cout 换成自己的流对象。

竞赛常用:freopen 重定向

#include <cstdio>
freopen("in.txt", "r", stdin);    // 之后 cin/scanf 就从文件读
freopen("out.txt", "w", stdout);  // 之后 cout/printf 就写到文件

一行重定向,正常写 cin/cout 即可,最省事。


第三部分:异常处理(try / catch)

程序运行时可能出意外(除以 0、越界、打不开文件)。C++ 用 异常处理 来”捕获”这些错误,避免程序直接崩溃。

try {
    // 可能出错的代码
    if (b == 0) throw "除数不能为 0";  // 抛出异常
    cout << a / b;
}
catch (const char* msg) {              // 捕获并处理
    cout << "出错了:" << msg;
}
  • try:把”可能出错”的代码包起来。
  • throw:出问题时抛出一个异常。
  • catch接住异常并处理,程序得以继续。

入门阶段了解机制即可;竞赛中用得不多,但能帮助理解”健壮的程序如何应对错误”。


第四部分:作用域解析运算符 ::

:: 用来指明”某个名字属于哪个作用域 / 命名空间”:

std::cout << "hi";   // 明确用 std 命名空间里的 cout

这就是为什么写了 using namespace std; 后可以省略 std::。类的成员函数在类外定义时也用 ::(如 Student::show())。


小结

  • 文件操作:<fstream>ifstream 读、ofstream 写,用法同 cin/cout;竞赛常用 freopen 重定向。
  • 异常处理:try 包住、throw 抛出、catch 接住,避免程序崩溃。
  • :: 作用域解析,指明名字归属。

课后小练

  1. 把 1~100 写入 out.txt,再从中读回求和。
  2. freopen 把一道题改成”从 in.txt 读、写到 out.txt”。
  3. 写一个除法程序,用 try/catch 处理”除数为 0”。