3

我正在尝试使用std::istream并希望使用异常来简化错误处理来解析文件。但是即使启用了,流也不会在eof上引发异常。

考虑以下代码段:

std::string line("Lorem ipsum");
std::istringstream is(line);
is.exceptions(std::ios::eofbit | std::ios::failbit);

std::string value1, value2, value3;
is >> value1;
std::cout << is.eof() << std::endl;
is >> value2;
std::cout << is.eof() << std::endl;
is >> value3;
std::cout << is.eof() << std::endl;

读取value2后,eof()返回true但在任何时候都不会抛出异常,即使流被指示这样做(参见第 3 行)。最后,value3包含一个空字符串。

我错过了什么?

以防万一:我正在使用作为 Xcode 4.6.1 一部分的 LLVM libc++(支持 C++11 的 LLVM C++)。

4

1 回答 1

3

我刚刚查看了 libc++ 实现和指定此行为的标准部分:

27.7.2.1 类模板 basic_istream [istream]/p3:

如果rdbuf()->sbumpc()rdbuf()->sgetc()返回traits::eof(),则输入函数,除非另有明确说明,否则会在返回之前完成其操作并执行setstate(eofbit),这可能会抛出 ios_base::failure(27.5.5.4)。

然后p4:

如果这些被调用函数之一引发异常,则除非另有明确说明,否则输入函数将设置badbit为错误状态。如果badbit是 on exceptions(),则输入函数在不完成其操作的情况下重新抛出异常,否则它不会抛出任何东西并继续进行,就好像被调用的函数返回了失败指示一样。

我相信这里的症结在于对“其中一个被调用的函数”的解释。我将该短语解释为指上一段中提到的所有功能,包括setstate(eofbit). 在这种解释下,libc++ 的行为是正确的,因为badbit未设置。

要获得您想要的行为,请执行以下操作:

is.exceptions(std::ios::eofbit | std::ios::failbit | std::ios::badbit);
于 2013-03-27T18:58:07.783 回答