AlgoNote 算法通关手册:LeetCode 0735 小行星碰撞——用栈模拟同向运动中的碰撞过程
2026/10/9 1:14:33
<fstream>:所有文件流操作的核心头文件,包含ifstream/ofstream/fstream三类核心文件流类;<iostream>:提供流基类和基础输入输出能力(如cin/cout),文件流类均继承自其基类;<string>:用于处理文件路径字符串、读写的文本内容;<cstdio>:补充文件重命名、删除等高级操作(兼容 C 标准库)。std::ifstream:只读文件流,专门用于从文件读取数据(文本 / 二进制均可),默认以ios::in模式打开;std::ofstream:只写文件流,专门用于向文件写入数据(文本 / 二进制均可),默认以ios::out | ios::trunc模式打开;std::fstream:读写文件流,支持同时读取和写入文件,默认以ios::in | ios::out模式打开。文件打开模式用于指定文件的操作规则,可通过|组合多个模式,所有模式均属于std::ios_base::openmode类型:
ios::inifstream的默认模式;ios::in | ios::binary(二进制只读模式)。ios::outofstream的默认模式;ios::out | ios::app(追加写模式)。ios::appios::binary\r\n/Linux 下\n)等特殊字符,直接读写原始字节;ios::truncios::out模式默认包含此属性;ios::app冲突,同时指定时app优先级更高。ios::atetellg())。ifstream为例):std::ifstream::ifstream(const std::string& path, std::ios_base::openmode mode = ios::in);// 只读打开文本配置文件(默认ios::in模式) std::ifstream config_in("config.txt"); // 追加模式打开日志文件(ios::out + ios::app) std::ofstream log_out("app.log", std::ios::out | std::ios::app);void std::ifstream::open(const std::string& path, std::ios_base::openmode mode = ios::in);std::fstream data_fs; // 读写+二进制模式打开数据文件 data_fs.open("data.bin", std::ios::in | std::ios::out | std::ios::binary);bool std::ifstream::is_open() const;true表示成功,false表示失败(路径错误、权限不足等);std::ifstream in("test.txt"); if (!in.is_open()) { std::cerr << "文件打开失败:test.txt" << std::endl; return 1; // 异常退出 }void std::ifstream::close();std::ofstream out("log.txt"); // 写入内容后显式关闭 out.close();std::istream& std::getline(std::istream& is, std::string& str);std::ifstream in("config.txt"); std::string line; // 逐行读取直到文件末尾 while (std::getline(in, line)) { std::cout << "读取行:" << line << std::endl; }std::ifstream in("num.txt"); // 文件内容:10 20 30 40 int num; // 逐个读取整数 while (in >> num) { std::cout << "读取数字:" << num << std::endl; }std::istream& std::istream::get(char& c);std::ifstream in("test.txt"); char ch; // 逐字符读取并输出 while (in.get(ch)) { std::cout << ch; }std::cout用法完全一致,向文件流写入格式化数据(字符串、数字、浮点数等);std::ofstream out("log.txt"); out << "程序启动时间:" << "2026-01-26" << std::endl; out << "用户ID:" << 1001 << " | 分数:" << 95.5 << std::endl;std::ostream& std::ostream::put(char c);std::ofstream out("char.txt"); // 链式写入字符,最终文件内容:Hello\n out.put('H').put('e').put('l').put('l').put('o').put('\n');std::istream& std::istream::read(char* buffer, std::streamsize count);// 读取4字节整数(二进制模式) std::ifstream in("data.bin", std::ios::in | std::ios::binary); int num; // 强制转换为char*,读取int大小的字节数 in.read(reinterpret_cast<char*>(&num), sizeof(num)); std::cout << "读取的整数:" << num << std::endl;std::ostream& std::ostream::write(const char* buffer, std::streamsize count);// 写入自定义结构体(二进制模式) struct Student { int id; char name[20]; float score; }; std::ofstream out("stu.bin", std::ios::out | std::ios::binary); Student s = {1001, "张三", 95.5f}; out.write(reinterpret_cast<const char*>(&s), sizeof(s));文件流通过「读指针(get)」和「写指针(put)」实现随机访问,读指针操作函数以g结尾,写指针以p结尾:
std::istream& std::istream::seekg(std::streampos pos);std::istream& std::istream::seekg(std::streamoff off, std::ios_base::seekdir dir);dir可选基准位置:ios::beg:从文件开头偏移;ios::cur:从当前指针位置偏移;ios::end:从文件末尾偏移;std::ifstream in("test.txt"); in.seekg(0, std::ios::end); // 指针移到文件末尾(用于获取文件大小) in.seekg(10, std::ios::beg); // 指针移到文件开头后第10字节std::streampos std::istream::tellg() const;std::ifstream in("test.txt"); in.seekg(0, std::ios::end); std::streampos file_size = in.tellg(); // 获取文件总字节数 std::cout << "文件大小:" << file_size << " 字节" << std::endl;seekg(),区别是操作写指针,适用于写文件或读写文件场景;std::fstream fs("data.bin", std::ios::in | std::ios::out | std::ios::binary); fs.seekp(5); // 写指针移到第5字节位置(绝对位置)tellg(),区别是返回写指针的当前位置;std::ofstream out("test.txt"); out << "Hello"; std::streampos pos = out.tellp(); // 返回5("Hello"共5字节)文件操作需检查流状态,避免操作失败导致程序异常:
bool std::ios::eof() const;true表示正常读取到末尾;std::ifstream in("test.txt"); std::string line; while (std::getline(in, line)) {} if (in.eof()) { std::cout << "文件读取完成(正常到达末尾)" << std::endl; }bool std::ios::fail() const;if (in.fail()) { std::cerr << "文件读取格式错误(非致命)" << std::endl; }bool std::ios::bad() const;if (in.bad()) { std::cerr << "文件读取致命错误(如文件损坏)" << std::endl; }void std::ios::clear(std::ios_base::iostate state = std::ios_base::goodbit);eof()为true后,需调用clear()才能继续操作);in.clear(); // 清除所有错误状态 in.seekg(0); // 重置读指针到文件开头std::rename(来自<cstdio>);#include <cstdio> if (std::rename("old.txt", "new.txt") != 0) { std::cerr << "文件重命名失败" << std::endl; }std::remove(来自<cstdio>);#include <cstdio> if (std::remove("tmp.txt") != 0) { std::cerr << "文件删除失败" << std::endl; }seekg()和tellg();std::ifstream in("test.bin", std::ios::binary); in.seekg(0, std::ios::end); // 指针移到末尾 int size = in.tellg(); // 获取字节数 in.seekg(0, std::ios::beg); // 移回开头,方便后续操作 std::cout << "文件大小:" << size << " 字节" << std::endl;#include <fstream> #include <iostream> #include <string> using namespace std; int main() { // 打开配置文件 ifstream config_in("config.conf"); if (!config_in.is_open()) { cerr << "配置文件打开失败:config.conf" << endl; return 1; } // 逐行读取并输出 string line; cout << "===== 配置文件内容 =====" << endl; while (getline(config_in, line)) { cout << line << endl; } // 检查读取状态 if (config_in.eof()) { cout << "\n配置文件读取完成" << endl; } config_in.close(); return 0; }#include <fstream> #include <iostream> #include <string> using namespace std; int main() { // 追加模式打开日志文件 ofstream log_out("app.log", ios::out | ios::app); if (!log_out) { cerr << "日志文件打开失败" << endl; return 1; } // 写入日志内容 log_out << "【INFO】程序启动成功 | 时间:2026-01-26 15:30:00" << endl; log_out << "【DEBUG】用户ID:1001 | 操作:登录" << endl; log_out.close(); cout << "日志写入完成" << endl; return 0; }#include <fstream> #include <iostream> using namespace std; // 自定义数据结构体 struct UserData { int id; char username[16]; double balance; }; int main() { // 1. 写入二进制数据 ofstream out("user_data.bin", ios::out | ios::binary); if (!out) { cerr << "写入文件打开失败" << endl; return 1; } UserData user = {1002, "李四", 5000.50}; out.write(reinterpret_cast<const char*>(&user), sizeof(user)); out.close(); // 2. 读取二进制数据 ifstream in("user_data.bin", ios::in | ios::binary); if (!in) { cerr << "读取文件打开失败" << endl; return 1; } UserData read_user; in.read(reinterpret_cast<char*>(&read_user), sizeof(read_user)); in.close(); // 输出读取结果 cout << "用户ID:" << read_user.id << endl; cout << "用户名:" << read_user.username << endl; cout << "余额:" << read_user.balance << endl; return 0; }#include <fstream> #include <iostream> #include <vector> #include <string> using namespace std; int main() { // 待打开的文件列表 vector<string> file_list = {"file1.txt", "file2.txt", "file3.txt"}; // 存储多个读流对象(使用移动语义,ifstream不可拷贝) vector<ifstream> file_ins; // 批量打开文件 for (const string& path : file_list) { ifstream in(path); if (!in) { cerr << "跳过失败文件:" << path << endl; continue; } file_ins.push_back(move(in)); // 移动语义存入容器 } // 批量读取每个文件 for (int i = 0; i < file_ins.size(); ++i) { cout << "\n===== 读取文件:" << file_list[i] << " =====" << endl; string line; while (getline(file_ins[i], line)) { cout << line << endl; } file_ins[i].close(); } return 0; }is_open():路径错误、权限不足、文件不存在等都会导致打开失败,未检查会引发后续操作崩溃;ifstream/ofstream/fstream均禁用拷贝构造和赋值,批量管理时需用std::move实现移动;ios::binary:读写图片、结构体等非文本数据时,不加此模式会导致换行符被篡改,数据错误;eof()/fail()为true后,流会进入错误状态,需用clear()清除后才能继续操作;close()能及时释放文件句柄,避免资源泄露;/(Windows 和 Linux 均支持),避免\(Windows 专属,需转义为\\)。getline()/<<读写,二进制文件用read()/write()+ios::binary;seekg()/tellg()/seekp()/tellp(),错误处理需结合eof()/fail()/clear();vector存储流对象并配合移动语义,避免拷贝错误。