unget有任何保证吗?

4

考虑以下事项:

char c;
cin >> c;
cin.unget();

假设char输入成功,unget能够保证至少可以回退一个字符吗?如果我请求并成功获取一个字符串,那么我可以保证被允许调用unget一直回退到该字符串的开头吗?

2个回答

7
保证您可以使用unget方法至少回退一个字符。如果要回退多个字符,仅取决于实现和情况,所以不应该假设可以回退多个字符。
编辑:抱歉,我想到了libc的int unget(int ch, FILE *stream)。 标准规定如下:
一个字符的回退是保证的。如果在同一流上调用ungetc函数太多次,而没有介入读取或定位操作,则该操作可能失败。
我将查找有关basic_istream<>& unget()的确切说法。
编辑:好的,这里是c ++标准对basic_istream<>& unget()的说明(我添加的加粗):
行为类似于未格式化的输入函数(如27.6.1.3第1段所述)。构造对象之后,如果!good()调用setstate(failbit),它可能会引发异常,并返回。如果rdbuf()不为null,则调用rdbuf() - & gt; sungetc()。如果rdbuf()为null或如果sungetc()返回traits :: eof(),则调用setstate(badbit)(这可能会抛出ios_base :: failure(27.4.4.3))。
因此,重要的部分是它调用了sungetc(),所以让我们看看标准对此的说明:
如果输入序列的回推位置不可用,则返回pbackfail()。否则,将输入序列的下一个指针减量,并返回traits :: to_int_type(* gptr())
我没有看到明确规定的限制,因此值得尝试。如果我理解正确,它将在支持流缓冲区中调整指针。因此,只要缓冲区中有足够的“历史记录”,它就应该继续成功。
但是与C不同,似乎您无法保证它会起作用,但是您很可能可以回退多个字符。
因此,我的建议是不要依赖回退多个字符,并始终检查是否失败。

1
如果您查看实现uflow()underflow()的要求,您可以推断出,如果streambuf曾经提供一个字符,则至少会有一个字符的回退缓冲区。 uflow()总是将一个字符从挂起序列转移到备份序列,这意味着在任何成功的sbumpc()之后必须至少有一个字符的备份。(如果您只执行了sgetc(),那么这实际上是一个“窥视”,因此您可能没有任何回退空间。) - CB Bailey

0

你应该考虑使用 std::istream::peek

它允许你在不从流中获取字符的情况下检查下一个可用字符。这样你就不必把它放回去 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接