【问题标题】:std::istream does not throw eof exception (that has been enabled)std::istream 不抛出 eof 异常(已启用)
【发布时间】:2013-03-27 12:30:39
【问题描述】:

我正在尝试使用std::istream 解析文件,并希望使用异常来简化错误处理。但是流永远不会在 eof 上抛出异常,即使它们已启用。

考虑以下 sn-p:

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++)。

【问题讨论】:

  • 在 Linux 上使用 g++ 为我工作
  • @parkydr:出于好奇:使用 g++ 的程序的输出是什么? value2 是否仍然读取而不抛出异常?
  • 0 在抛出 'std::ios_base::failure' 实例后调用终止 what(): basic_ios::clear Aborted (core dumped)

标签: c++ stl llvm istream


【解决方案1】:

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

27.7.2.1 类模板 basic_istream [istream]/p3:

如果rdbuf()-&gt;sbumpc()rdbuf()-&gt;sgetc() 返回traits::eof(),则 输入函数,除非另有明确说明,否则完成 它的动作和setstate(eofbit),这可能会抛出 ios_base::failure (27.5.5.4),在返回之前。

然后是 p4:

如果这些被调用函数之一抛出异常,则除非 另有明确说明,输入函数设置 badbit 错误 状态。如果badbitexceptions() 中打开,则输入函数重新抛出 异常没有完成它的动作,否则它不会 抛出任何东西并继续进行,就好像被调用的函数返回了一个 故障指示。

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

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

is.exceptions(std::ios::eofbit | std::ios::failbit | std::ios::badbit);

【讨论】:

  • 在我看来,27.7.2.1 中的关键词是“可能”。
  • @Howard:我观察到了所描述的行为,似乎可以这样解释规范。但是,在std::ios::eofbit 上请求异常除了设置std::ios::badbit 而不是真正抛出任何东西(从用户的角度来看)之外没有任何影响。
  • 如果您不同意标准的指定方式,这:open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#submit_issue 始终是您的选择。
猜你喜欢
  • 2018-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-13
  • 1970-01-01
  • 2021-05-28
相关资源
最近更新 更多