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

时间:2015-10-08 12:10:52

标签: c++ iostream

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

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

这样可以正常工作 - 除了之外,因为输入流只在之后指示EOF ,当它到达输入流的末尾时(<{1}它读入并发出一个空字符串:

^D

我们可以通过使输出行以[begin] < a b c > -a- > -b- > -c- < (^D) > -- [end] 为条件来处理这个问题。

然而还有其他选择。我们可以替换这一行:

!s.empty()

使用:

while (std::cin)

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

operator>>

我的问题有三个:

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

1 个答案:

答案 0 :(得分:2)

std::istream::sentry用于在输入函数中使用。正确解决您的问题的方法是始终检查流是否正常,即在读取后读取成功

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

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

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