2

我正在使用以下循环从两个文件中读取数字,直到两个文件都用完:

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
}

我的程序有效。但它能保证按标准工作吗?也就是说,是否允许我继续从失败的流中读取,或者实现可以选择抛出异常?

4

2 回答 2

2

简短回答:是的,您可以尝试从流中输入任意次数的内容。即使尝试从该流中输入某些内容失败。所发生的一切是,在尝试输入内容失败后的所有尝试输入内容也将失败。

长答案:operator >>表现为格式化输入函数[istream.formatted.arithmetic]。格式化输入函数构造一个本地哨兵对象,并且仅当将该哨兵对象转换bool为值true [istream.formatted.reqmts]时才执行输入。默认情况下(如果您没有通过向流提供自定义字符特征来覆盖此行为),std::sentry将使用类型对象。仅当为[istream::sentry]std::sentry时,才会为流构造一个。仅当 failbit 、 badbit 和 eofbit 均未设置时才返回 true [iostate.flags]/7。如果truegood()true good()operator >>(int&)尝试输入(由于成功构建和检查哨兵)但未能这样做,它将设置失败位[istream.formatted.arithmetic]/3。如果设置了流的异常掩码中的相应标志(默认不设置),设置failbit将导致抛出异常[iostate.flags]/6 [iostate.flags]/5。否则,流将只是处于失败状态,并且哨兵对象的构造将导致false下一次,直到您调用clear()......</p>

我会考虑重写这段代码,例如

do
{
    if (int a; file1 >> a)
        ; // use a
    if (int b; file2 >> b)
        ; // use b
} while (file1 || file2);
于 2019-12-17T10:55:13.423 回答
0

是的,你可以这样做。一旦流处于失败状态(failbit),进一步的读取也将失败,但这是您想要发生的。这些读取不会引发异常 - 只有通过流的exceptions()方法显式启用,failbit 才会生成异常。根据这个来源,默认是不启用这些异常:

默认情况下,所有流都有好位(由于设置了错误状态标志,它们不会抛出异常)。

于 2019-12-17T11:08:25.040 回答