unget有任何保证吗

Are there any guarantees with unget?

本文关键字:任何保 unget      更新时间:2023-10-16

考虑以下因素:

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

假设字符输入成功,unget是否保证能够备份至少一个字符?如果我请求并成功获得一个字符串,是否可以保证我可以一直调用unget到该字符串的开头?

您保证能够unget至少1个字符。任何多个都取决于实现和环境,所以您不应该假设您可以unget多个。

编辑:很抱歉我想到了libc的int unget(int ch, FILE *stream)。标准上说:

推回的一个特点是保证。如果ungetc函数为在同一个电话上打了太多次没有插入读取的流对的文件定位操作流,操作可能会失败。

我会看看我是否能准确地找到关于basic_istream<>& unget() 的说法

编辑:好的,下面是c++标准对basic_istream<>& unget()的描述(我加了粗体):

表现为未格式化的输入功能(如27.6.1.3所述,第1段)。在构建sentry对象,如果!good()调用setstate(failbit)可能抛出异常和返回。如果rdbuf()为不为null,调用rdbuf()->sungetc()。如果rdbuf()为空,或者如果sungetc()返回traits::eof(),调用setstate(badbit)(可能抛出ios_base::failure(27.4.4.3))。

所以重要的一点是它调用sungetc(),让我们看看标准是怎么说的:

如果输入序列返回位置不可用,返回pbackfail()。否则,递减下一个指针用于输入序列并返回CCD_ 18。

我没有看到任何明确说明限制的内容,所以值得一试。如果我正确理解这一点,它将调整后台流缓冲区中的指针。因此,只要缓冲区中有足够的"历史",它就应该继续取得成功。

然而,与C不同的是,你似乎永远无法保证它会起作用,但你很可能会回退多个字符。

因此,我的建议是,不要依赖于放回多个字符,并始终检查是否失败。

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

它允许您检查下一个可用的字符,而无需将其从流中删除。这样你就不必把它放回去了:)