为什么std::ifstream会自动关闭?getline未找到分隔符异常问题
问题原因解释
流状态设置不等于文件关闭
你观察到的“文件自动关闭”是误判。std::ifstream::getline当读取字符数达到第二个参数指定的上限(你这里设置的是16,实际最多读取15个有效字符+1个字符串终止符)时,还未找到分隔符|,就会给流设置failbit标记,流会暂停后续IO操作,但文件本身并没有被关闭。错误的错误信息打印方式
你调用strerror(File.rdstate())的用法是完全错误的:
File.rdstate()返回的是C++标准库定义的流状态位掩码,不属于系统errno错误码范畴strerror只能接收系统errno的错误码,传入流状态位得到的输出没有实际参考意义- 第一次读取成功时
rdstate()返回goodbit(值为0),所以strerror(0)输出No error符合预期 - 第二次读取触发
failbit时,rdstate()返回的failbit对应值为4,而系统errno中4刚好对应ENOENT(无此文件或目录),这就是你看到错误输出的来源,和文件是否关闭没有任何关系。
- 第一次读取成功时
- 原有代码的其他逻辑问题
你写的if (strlen(Buffer) == 0) break逻辑不符合需求,遇到文件里的空分隔槽(也就是||的情况)会直接终止读取,导致后面的有效姓名无法被读取。
修正代码参考
可以直接用std::getline搭配std::string避免缓冲区溢出问题,不需要手动指定固定大小的缓冲区:
#include <iostream> #include <fstream> #include <vector> #include <string> int main() { std::ifstream File("File.txt"); if (!File.is_open()) return -1; std::vector<std::string> Names; std::string Buffer; // 第三个参数指定分隔符为| while (std::getline(File, Buffer, '|')) { // 如果需要保留空槽就去掉判断,不需要的话可以判断Buffer非空再push Names.push_back(Buffer); } // 输出验证 for (const auto& name : Names) { std::cout << "姓名: " << (name.empty() ? "[空槽]" : name) << "\n"; } return 0; }
内容的提问来源于stack exchange,提问作者Azazel
相关产品推荐
相关产品推荐

