考虑以下简单程序,该程序将输入拆分为空白并打印出每行一个非空白标记:
#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>>
我的问题有三个:
答案 0 :(得分:2)
std::istream::sentry
用于在输入函数中使用。正确解决您的问题的方法是始终检查流是否正常,即在读取后读取成功:
for (std::string s; std::cin >> s; ) {
std::cout << '-' << s << "-\n";
}
流在读取之前无法知道读取操作是否成功。完成后,它就知道了。
使用sentry
的方法通常适用于字符串,但对于需要任何格式的类型,它可能会失败。例如,如果您需要阅读int
,则使用sentry
跳过该空格并不表示是否可以读取int
。即使使用std::string
,该方法也可能失败:流可以在首次访问时提供字符,但在第二次访问时失败。第一次访问是确定该字符不是来自sentry
构造函数的空格,而后面是字符串读取失败。