[英]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.