fstream:检查错误的最正确方法
fstream: the most correct way to check for errors
我想围绕fstream
类编写一个包装器。正如我所看到的,检查流是否正常工作的最常见方法是查看good()
函数的结果。然而,我听说这主要是历史函数,使用它并不安全(更准确地说,可能会有一些情况下,流工作不好,但函数返回true
。所以我想分享经验,并从其他人那里知道什么是检查fstream
错误的最正确方法。
如果有可能检查不同类型的错误,比如文件不存在、只能打开读取等,那就太好了。也有必要让这些程序跨平台运行(然而,主要目标是Linux)。
提前感谢!
如果文件操作失败,eof()
返回false
,则可以检查errno
或GetLastError
(取决于平台)以找出问题所在。
我实际上只有两个建议,它们都依赖于用重载的!
运算符的返回值检查打开的流。使用仅输入模式,只需检查文件是否存在:
char name[] = "C:\some_folder\some file.txt";
std::ifstream f;
f.open(name, std::ios::in);
if (!f)
printf("File does not exist, or inadequate permissions");
f.close();
以输入/输出模式打开,以防止在计划执行写入操作时被截断:
std::fstream f;
f.open(name, std::ios::in | std::ios::out);
if (!f)
printf("Could not open file");
f.close();
默认情况下,这些是相应流的输入参数,但为了澄清起见,我已经明确显示了它们。
在检查eof等的读/写操作期间,这个问题的第一个答案看起来很有见地。
good()
/bad()
只测试badbit
,它只涵盖一些,并且大多数是不可恢复的错误。要检查错误,您需要同时检查failbit
和badbit
。有关何时设置这些位的更多详细信息,请参阅iosstate
。
要检查错误,请使用fail()
,它同时检查failbit
和badbit
:
if (stream.fail()) { /* handle error ... */ }
C++流还重载运算符bool
以返回!fail()
,因此您可以简单地执行
if (!stream) { /* handle error ... */ }
然后您可以从errno
中获得最后一个错误,并使用strerror()
:将其转换为文本
std::ifstream f("my_file");
if (!f) {
std::cerr << std::strerror(errno) << std::endl;
return 1;
}
请注意,failbit
包括eofbit
(从某种意义上说,尝试在EOF下读取将设置两个位),因此要检查读取错误,需要排除eofbit
:
std::string line;
while (std::getline(f, line)) {
// process line
}
if (!f && !f.eof()) {
std::cerr << std::strerror(errno) << std::endl;
}
- C++:正在检查LinkedList中的回文-递归方法-错误
- 检查哪个对象调用了另一个对象的对象方法
- 检查两个节点在子节点上是否具有相同状态的更优雅的方法
- 检查类是否在方法中实例化
- 检查类方法中是否(此 == nullptr)
- 检查子类型时的专用方法模板
- 检查两个向量是否并行的最有效方法
- 如何检查在编译时是否调用了模板化方法?
- 尝试编译SFINAE检查中使用的方法体时发生编译错误
- 有没有一种简单的方法来检查C++中的不安全表达式
- 是否有更有效的方法来检查元素是否在给定的区间内
- 检查特定目录中是否存在与文件匹配的 abc* 的最佳方法
- 检查数组是否等于的最快方法?
- 替换枚举以最大化编译时间检查的最佳方法
- 双重检查创建单例问题的方法
- 如果方法不进行类型检查,为什么C++模板匹配?
- C++:检查向量中的元素是否大于另一个具有相同索引的元素的有效方法?
- 检查子类是否执行了方法重写
- 最快/最小方法检查字符串是否包含多个单词
- SFINAE c++方法检查