std::istream:: sentinel与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))
哨兵对象(通常由operator>>
内部使用)具有消耗空白和然后检查EOF或其他流状态的效果:
[begin]
< a b c
> -a-
> -b-
> -c-
< (^D)
[end]
我的问题有三个:
- 有什么原因导致这个结构不能像预期的那样工作吗?
- 已经是习惯用语了吗?
- 如果没有,为什么没有?
std::istream::sentry
在输入函数中使用。解决问题的正确方法是总是检查流是否正常,即在 reading:
for (std::string s; std::cin >> s; ) {
std::cout << '-' << s << "-n";
}
流不能提前知道读操作是否成功。完成后,它就知道了。
使用sentry
的方法通常对字符串有效,但对于需要任何格式的类型可能会失败。例如,如果您需要读取int
,跳过与sentry
的空格并不表示是否可以读取int
。即使使用std::string
,这种方法也可能失败:流可能在第一次访问时提供一个字符,但在第二次访问时失败。第一次访问是从sentry
的构造函数中确定字符不是空格,然后从字符串中读取失败。
相关文章:
- 将无符号char*转换为std::istream*C++
- 使用std::istream::peek()总是安全的吗
- 如何将QByteArray转换为std::istream或std::ifstream?
- 如何使 std::istream 从键盘获取输入(如 std::cin)?
- 为什么 std::istream::gcount 返回的字符比预期的多一个字符
- std :: iStream到未签名的数值,如何检测负值
- 是否可以覆盖 std::istream 读取方法?
- 此功能希望从std :: istream解析该功能的输入格式
- 包装 std::istream 时出现问题,移动后unique_ptr不为空
- 为什么std :: istream ::忽略丢弃字符
- 如何从 std::istream 加载 wxXml文档?
- STD :: Istream意外结束
- 为什么在空流上呼叫时,std :: istream ::忽略不返回
- 如何从 c++ std::istream 读取固定数量的字节
- 在构造函数中从 std::istream 初始化 const 类数据成员
- Reading LLVM IR from a std::istream
- 处理从 std::istream 中提取字符串的空字符串大小写
- 如何从“std::istream”加载XML文档
- 如何安全地读取std::istream中的行
- 使用 std::istream 运行函数