我正在使用以下循环从两个文件中读取数字,直到两个文件都用完为止:
int a, b;
while (file1 >> a, file2 >> b, file1 || file2) {
if (file1 && file2) ... // use of both a and b
if (file1) ... // use of a
if (file2) ... // use of b
}
我的程序有效。但是可以保证按标准工作吗?也就是说,是否允许我继续从失败的流中读取,或者实现可以选择引发异常?
答案 0 :(得分:2)
简短的回答:是的,您可以尝试从流中输入任意次数的内容。即使尝试从该流中输入内容,也失败了。将会发生的所有事情是,在尝试输入某项内容失败之后,所有尝试输入某项内容的尝试也会失败。
长答案:operator >>
表现为格式化的输入函数[istream.formatted.arithmetic]。格式化的输入函数将构造一个本地哨兵对象,并且仅在将该哨兵对象转换为bool
并产生值true
[istream.formatted.reqmts]时才执行输入。默认情况下(如果您没有通过向流提供自定义字符特征来覆盖此行为),将使用类型std::sentry
的对象。仅当std::sentry
为true
[istream::sentry]时,为流构造的good()
的值为true
。只有{failbit,badbit或eofbit都未设置[iostate.flags]/7时,good()
才返回true。如果operator >>(int&)
尝试输入(由于成功构建并检查了岗哨),但没有输入,它将设置故障位[istream.formatted.arithmetic]/3。如果设置了流的异常掩码中的相应标志(默认情况下未设置),则设置故障位将导致引发异常[iostate.flags]/6 [iostate.flags]/5。否则,流将仅处于失败状态,并且构造哨兵对象将导致下次false
,直到您调用clear()
…
例如,我会考虑重写此代码
do
{
if (int a; file1 >> a)
; // use a
if (int b; file2 >> b)
; // use b
} while (file1 || file2);
答案 1 :(得分:0)
是的,您可以这样做。一旦流处于失败状态(失败位),进一步的读取也会失败,但这就是您想要发生的事情。这些读取将不会抛出异常-仅当通过流的exceptions()方法显式启用了异常时,故障位才会生成异常。根据{{3}},默认情况是未启用以下例外:
默认情况下,所有流都具有好习惯(由于设置了错误状态标志,它们不会引发异常)。