首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用std::istream::std::istream

使用std::istream::std::istream
EN

Stack Overflow用户
提问于 2015-10-08 12:10:51
回答 1查看 752关注 0票数 2

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

代码语言:javascript
复制
#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)的末尾时,它读取并发出一个空字符串:

代码语言:javascript
复制
[begin]
< a b c
> -a-
> -b-
> -c-
< (^D)
> --
[end]

我们可以通过使输出行以!s.empty()为条件来处理这一问题。

然而,还有另一个选择。我们可以替换这条线路:

代码语言:javascript
复制
while (std::cin)

通过以下方式:

代码语言:javascript
复制
while (std::istream::sentry(std::cin))

sentry对象(通常由operator>>在内部使用)的效果是使用空白,然后检查EOF或其他流状态:

代码语言:javascript
复制
[begin]
< a b c
> -a-
> -b-
> -c-
< (^D)
[end]

我的问题有三个:

  • 有什么原因可以解释为什么这个构造不能像预期的那样工作?
  • 已经习以为常了吗?
  • 若否,原因为何?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-10-08 12:21:59

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

代码语言:javascript
复制
for (std::string s; std::cin >> s; ) {
    std::cout << '-' << s << "-\n";
}

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

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33015411

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档