fstream EOF异常抛出
fstream EOF unexpectedly throwing exception
我的问题与上一个问题非常相似。我想打开并读取一个文件。我希望在文件无法打开时抛出异常,但我不希望在EOF时抛出异常。fstreams似乎让您独立控制是否在EOF、失败和其他错误的情况下抛出异常,但似乎EOF也倾向于映射到错误和/或失败异常。
这是我试图做的一个简单的例子。函数f()应该在文件包含某个单词时返回true,如果不包含则返回false,并且如果(例如)文件不存在则抛出异常。
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
bool f(const char *file)
{
ifstream ifs;
string word;
ifs.exceptions(ifstream::failbit | ifstream::badbit);
ifs.open(file);
while(ifs >> word) {
if(word == "foo") return true;
}
return false;
}
int main(int argc, char **argv)
{
try {
bool r = f(argv[1]);
cout << "f returned " << r << endl;
} catch(...) {
cerr << "exception" << endl;
}
}
但是它不起作用,因为使用操作符>>的基本fstream读取显然是EOF设置坏位或失败位的操作之一。如果文件存在且不包含"foo",则该函数不会按预期返回false,而是抛出异常。
当文件到达末尾时试图提取时,也会设置std::ios_base::failbit
标志,这是流的布尔运算符允许的行为。您应该在f()
中设置一个额外的try-catch块,如果它不符合文件结束条件,则重新抛出异常:
std::ifstream ifs;
std::string word;
ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try {
ifs.open(file);
while (ifs >> word) {
if (word == "foo") return true;
}
}
catch (std::ios_base::failure&) {
if (!ifs.eof())
throw;
}
return false;
如果目标是仅在打开文件时出现问题时抛出异常,为什么不这样写:
bool f(const char *file)
{
ifstream ifs;
string word;
ifs.open(file);
if (ifs.fail()) // throw only when needed
throw std::exception("Cannot open file !"); // more accurate exception
while (ifs >> word) {
if (word == "foo") return true;
}
return false;
}
你当然可以设置:
ifs.exceptions(ifstream::badbit);
在之前或之后打开,以抛出异常,以防在读取过程中发生非常糟糕的事情。
basic_ios::operator bool()
检查fail()
,不检查!good()
。在达到EOF后,循环尝试再读取一个单词。如果没有提取字符,operator>>(stream&, string&)
将设置failbit
。这就是为什么你总是用一个异常退出。
这是很难避免的。流到达EOF状态不是在读取最后一个字符时,而是在尝试读取超过最后一个字符时。如果这发生在单词的中间,则没有设置failbit
。如果它发生在开头(例如,如果输入末尾有空格),则设置failbit
。你不可能真正可靠地结束在eof() && !fail()
状态
- 如何确定我已使用非编码文件到达 EOF?
- 处理多个异常集合的C++方法
- 我在c++代码中生成了一个运行时#3异常
- 孤立代码块在结构中引发异常
- C++中的赋值发生,尽管右侧出现异常
- 从构造函数抛出异常时如何克服内存泄漏
- 异常属于C++中的线程还是进程
- 当类定义不可见时捕获异常
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- 为什么异常不退出程序?
- 为什么我应该在异常处理中使用std::cerr而不是std::cout
- 如何修复链表类实现的未处理异常0xDDDDDDDD
- 关于:C++中异常对象的范围:为什么我没有得到副本?
- 是什么导致了Unity 3D中的"错误线程异常"?
- 如何将strftime中的格式错误作为异常捕获
- 创建具有 new in 函数和"this is nullptr"异常的对象
- fstream EOF异常抛出
- Std::istream不会抛出eof异常(已启用)
- 捕获istream忽略的(eof-)异常
- c++ fstream:当到达eof时抛出异常