支持通配符SSL证书、多域名证书、IP证书。适配ACME接口, 支持Zerossl、Let's Encrypt和Google等渠道。登录已有账号
2026-06-24 13:15:37 C++ 文件读取 ifstream fstream C风格文件操作 编程经验
读文件这件事,在C++里能绕的弯子其实不多,但每次有人问我“该用哪种”,我发现问题的关键往往不在语法上,而在场景上——你是不是在维护老代码、有没有混用C库的需求、团队规范允不允许。
所以这里把三种常用方式一并列出来,顺带说几句实际选型时的考虑。
如果只是读一个文本文件,逐行处理,那ifstream基本就是最省事的选择。代码长这样:
#include <iostream>
#include <fstream>
#include <string>
int main() {
std::ifstream file("example.txt");
if (!file.is_open()) {
std::cerr << "无法打开文件" << std::endl;
return 1;
}
std::string line;
while (std::getline(file, line)) {
std::cout << line << std::endl;
}
file.close();
return 0;
}
几个点值得提一下。头文件别忘了fstream和string,只include iostream是不行的,编译器报错的时候才想起来的人不在少数。
is_open()这个检查最好养成习惯,文件不存在或者权限不够的时候,不检查就直接getline,后面排查起来很浪费时间。另外getline每次读一行,不会把换行符带进来,输出的时候如果需要保留原始格式,记得自己补endl或者\n。
关于close()——实际上ifstream析构的时候会自动关闭文件,所以这个示例里手动调close()并不是必须的。
但如果文件生命周期比较长,或者你需要在函数中间提前释放文件句柄,那显式关闭是个好习惯。这里其实容易踩坑:有些人以为close()之后还能重新打开同一个对象用,结果发现状态位没清干净,读不出来东西。正确的做法是调完close()再调clear(),或者直接重新构造一个。
fstream是ifstream的父类(严格说是basic_fstream),能读能写,打开的时候指定模式就行。只读场景下和ifstream几乎一样:
#include <iostream>
#include <fstream>
#include <string>
int main() {
std::fstream file("example.txt", std::ios::in);
if (!file.is_open()) {
std::cerr << "无法打开文件" << std::endl;
return 1;
}
std::string line;
while (std::getline(file, line)) {
std::cout << line << std::endl;
}
file.close();
return 0;
}
跟上面ifstream的版本比,就多了一个std::ios::in参数。那为什么还要单独提fstream?因为有些场景下你确实需要同一个文件对象既读又写——比如先读配置再追加日志。这时候ifstream不够用,ofstream也不够用,fstream正合适。用std::ios::in | std::ios::out打开就行。
不过读写模式混用的时候,文件指针位置要自己管理好,seekg和seekp该用就用,不然很容易读到空或者把数据写飞。
在很多嵌入式项目或者C库比较重的环境里,fopen、fgets、fclose这套东西仍然大量存在。写法如下:
#include <iostream>
#include <cstdio>
int main() {
FILE* file = fopen("example.txt", "r");
if (file == nullptr) {
std::cerr << "无法打开文件" << std::endl;
return 1;
}
char buffer[256];
while (fgets(buffer, sizeof(buffer), file) != nullptr) {
std::cout << buffer;
}
fclose(file);
return 0;
}
这里有个很多人会绕进去的地方:fgets会在缓冲区够大的情况下把换行符也读进来,所以输出的时候buffer本身就带着\n,不需要额外补endl。如果你习惯性补了一个,行间距会翻倍,看起来很奇怪。另外buffer大小是256,如果某一行超过255个字符,fgets会截断,下一轮循环接着读剩下的部分。这个行为在处理不规则日志的时候要留个心。
C风格的文件操作没有RAII护体,fclose忘记调用的话句柄泄漏是实打实的。所以如果项目中允许用C++,ifstream更安全。
但有一种情况我会主动用C风格——需要用到某些只接受FILE*参数的C库函数,这时候你拿ifstream反而要绕一圈转成文件描述符,不如直接用fopen来得干净。
没有哪种绝对更好,看具体情况。新项目、纯C++环境、只读文本文件——ifstream,简单直接。需要同一个对象读写文件——fstream。老项目、C库交互频繁、或者团队本身就以C为主——用fopen那套,别硬上流。线上跑起来问题就出来了的那种,往往不是语法没写对,而是选的方式和项目上下文不搭。
从越界导致的未定义行为聊起,理清NULL误用,整理at()、边界检查等安全写法,以及几个能让程序稳一点的小优化。
本文深入探讨在C++中如何高效合并两个`vector
C++ `vector`越界访问是导致程序崩溃和数据损坏的常见陷阱。本文将深入剖析其未定义行为的原理,辨析`NULL`与`nullptr`的易混淆点,并提供一系列安全访问策略,如边界检查、`at()`方法应用及避免错误的指针比较,助您编写健壮、高效的C++代码。