用 std::ifstream 和 std::ofstream 读写文本文件最稳妥;二进制文件必须显式加 std::ios::binary 标志,否则 Windows 下易出错;注意文件打开模式、流位置指针重定位及同步设置。

用 std::ifstream 和 std::ofstream 读写文本文件最稳
绝大多数情况,别碰 fopen 或 FILE*,C++ 标准流更安全、自动管理资源、异常可控。默认按文本模式打开,换行符会自动转换(\r\n → \n),这点在 Windows 上尤其要注意。
常见错误:用 std::ofstream 打开已存在文件却没加 std::ios::app,结果内容被清空;或读取时没检查 is_open() 就直接 >>,导致后续操作静默失败。
- 写入前务必检查
file.is_open(),否则operator 不报错但不生效 - 读取整行用
std::getline(file, line),别用>>——后者遇空格/换行就停,容易漏数据 - 中文路径在 Windows 下可能乱码,建议用
std::filesystem::u8path()转 UTF-8 字符串再传给流(C++20 起)
二进制文件必须显式指定 std::ios::binary
不加这个标志,Windows 下读写 .png、.exe 这类二进制文件会出问题:流可能把 0x1A 当作 EOF,或把 \r\n 错误替换,导致文件损坏。
典型场景:保存序列化结构体、读取图片原始字节、处理音频帧数据。
立即学习“C++免费学习笔记(深入)”;
-
std::ofstream file("data.bin", std::ios::binary);—— 缺少std::ios::binary是 Windows 上二进制写入失败的头号原因 - 用
write()/read()成员函数,传地址和字节数:file.write(reinterpret_cast<const char>(&data), sizeof(data));</const> - 结构体含指针或虚函数时不能直接
write(),会写入无效地址——必须手动序列化字段
std::fstream 双向操作要小心打开模式组合
想同一个对象既读又写,不能只写 std::fstream f("a.txt");,默认是输入模式,写会失败。必须明确组合标志,且注意位置指针共享。
常见错误:打开时用了 std::ios::in | std::ios::out 却没加 std::ios::trunc 或 std::ios::app,结果文件被清空却不自知;或读完没调 seekg() 就写,数据插在文件开头而非末尾。
- 覆盖写:用
std::ios::in | std::ios::out | std::ios::trunc - 追加写:用
std::ios::in | std::ios::out | std::ios::ate,然后seekg(0, std::ios::end)定位 - 每次读写切换后,记得用
seekg()或seekp()显式重定位,流不会自动跳转
大文件读写性能差?先关掉 std::ios::sync_with_stdio(false)
默认情况下,C++ 流和 C 的 stdio 同步,带来额外锁和缓冲刷新开销。读写几百 MB 文件时,这一步能提速 2–3 倍。
但要注意副作用:关闭同步后,不能再混用 std::cout 和 printf,输出顺序不可控;且 std::cin/std::cout 与 scanf/printf 不能交叉调用。
- 全局关同步:在
main()开头加std::ios::sync_with_stdio(false); - 如果还要用
std::cin输入,记得额外加std::cin.tie(nullptr);解绑输出缓冲 - 文件流本身不受影响,但如果你在程序里同时用了
std::cout打日志,就得统一风格——要么全 C++ 流,要么全 C 风格
真正麻烦的不是语法,是二进制模式漏标、文本换行符隐式转换、还有流位置指针那种看不见摸不着的偏移。这些地方一错,程序跑得通,数据就悄悄坏了。



















