繁体   English   中英

std::istream::sentry 与 std::istream 的使用

[英]Use of std::istream::sentry with std::istream

考虑以下简单程序,该程序将输入拆分为空白并每行打印一个非空白标记:

#include <iostream>
int main(int argc, char* argv[])
{
        while (std::cin)
        {
                std::string s;
                std::cin >> s;
                std::cout << "-" << s << "-\n";
        }
        return 0;
}

这工作正常 - 除了因为输入流仅我们尝试从中读取后才指示 EOF,当它到达输入流( ^D )的末尾时,它会读入并发出一个空字符串:

[begin]
< a b c
> -a-
> -b-
> -c-
< (^D)
> --
[end]

我们可以通过使输出行以!s.empty()条件来解决这个问题。

然而,还有另一种选择。 我们可以替换该行:

while (std::cin)

和:

while (std::istream::sentry(std::cin))

sentry 对象(通常由operator>>内部使用)具有消耗空格然后检查 EOF 或其他流状态的效果:

[begin]
< a b c
> -a-
> -b-
> -c-
< (^D)
[end]

我的问题有三个:

  • 有什么理由说明这个结构不能按预期工作吗?
  • 它已经是惯用语了吗?
  • 如果没有,为什么不呢?

std::istream::sentry用于输入函数内部 解决您的问题的正确方法是始终检查流是否良好,即读取读取成功:

for (std::string s; std::cin >> s; ) {
    std::cout << '-' << s << "-\n";
}

流无法在读取之前知道读取操作是否会成功。 完成后,它就知道了。

使用sentry的方法通常适用于字符串,但对于需要任何格式的类型可能会失败。 例如,如果您需要读取一个int跳过与sentry的空格并不表示是否可以读取一个int 即使使用std::string该方法也可能失败:流可以在第一次访问时提供一个字符,但在第二次访问时失败。 第一次访问是确定字符不是来自sentry的构造函数的空格,然后是从字符串读取失败。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM