最稳用std::ifstream和std::ofstream读写纯文本,自动处理换行符转换、异常可控;须检查is_open()和fail(),用getline()按行读、避免>>截断,路径用filesystem::path,写入慎用endl。

用 std::ifstream 和 std::ofstream 读写纯文本最稳
别碰 fopen 或 FILE*,C++ 原生流在文本处理上更一致、自动处理换行符转换(比如 Windows 的 \r\n 读进来统一成 \n),且异常可控。默认构造时没指定 std::ios::binary 就是文本模式。
常见错误:用 std::fstream 同时读写却忘了加 std::ios::in | std::ios::out,或打开失败后直接操作流——is_open() 必须检查。
-
std::ifstream只读,适合逐行读取日志、配置等;std::ofstream只写,适合生成报告、导出数据 - 打开失败时,
failbit会被置位,但不会抛异常——除非你手动调用exceptions(std::ios::failbit | std::ios::badbit) - 路径含中文或空格?用
std::filesystem::path构造再转c_str()更可靠,尤其在 Windows 下
std::getline() 读行比 operator>> 安全得多
operator>> 遇到空格、制表符、换行就停,根本读不全带空格的字段;而 std::getline() 按换行符切分,才是真·按行读。
典型翻车现场:用 file >> str 读 CSV 第一列,结果第二列被截断,第三列根本没读到。
立即学习“C++免费学习笔记(深入)”;
- 用
std::getline(in, line)读整行,再用std::stringstream解析字段,避免格式错位 - 如果文件末尾缺换行符,
std::getline()仍能读出最后一行内容,但eof()要在下次调用后才返回 true —— 别靠while (!in.eof())控制循环 - 想跳过空行?读完判断
line.empty()或line.find_first_not_of(" \t") == std::string::npos
写文件时别漏掉 std::endl 或 \n,也别滥用 std::flush
没换行符,所有输出会挤在一行;而每写一行都跟 <code>std::endl,等于每次强制刷缓冲区,IO 开销翻倍。
真实场景里,日志要实时可见,CSV 导出只关心最终结果——策略完全不同。
- 普通写入用
\n即可,系统级缓冲会自动管理效率;只有调试或关键日志才用std::endl - 写完必须检查
out.fail(),尤其是磁盘满、权限不足时,operator 不报错但写不进去 - 关闭文件前不用手动
flush(),std::ofstream析构时自动 flush;强行 flush 反而拖慢批量写入
中文路径和 UTF-8 文本在 Windows 下容易乱码
Windows 默认用本地编码(如 GBK),但现代编辑器保存文本基本是 UTF-8。流对象本身不处理编码转换,它只是字节搬运工。
不是 fstream 有 bug,是你没告诉系统“这串字节该当 UTF-8 解释”。Linux/macOS 默认 UTF-8,所以问题不明显。
- Windows 上读写 UTF-8 文本,推荐用
std::wifstream/std::wofstream+std::locale绑定 UTF-8 facet(需 C++11+),或改用第三方库如utf8cpp - 快速验证:用记事本另存为“UTF-8 无 BOM”,再用 VS 的“文件 → 高级保存选项”确认编码
- 绝对不要依赖
SetConsoleOutputCP(CP_UTF8)来修复文件读写——那是控制台显示的事,和文件流无关
编码和换行符处理是跨平台文件操作里最容易被跳过的两步,尤其当测试只在一种系统上跑通时。











