【问题标题】:Difference between putback() and unget()putback() 和 unget() 的区别
【发布时间】:2011-07-20 22:43:21
【问题描述】:

我正在使用标准 iostream 从文件中获取一些输入,我对 unget()putback(character) 感到困惑。在我看来,这些功能实际上是相同的,unget() 只记得输入的字符,所以我很紧张。我一直使用putback(character),但character 始终是最后读取的字符,我一直在考虑更改为unget()putback(character) 是否总是与 unget() 相同,如果 character 始终是最后读取的字符?

【问题讨论】:

    标签: c++


    【解决方案1】:

    你不能对unget() 撒谎。它“取消”最后读取的字符。你可以用putback(c) 说谎。您可以“放回”除上次读取字符之外的某些字符。有时放回最后读取字符以外的字符会很有用。

    另外,如果底层读取缓冲区确实具有缓冲能力,您可以“放回”多个字符。我认为ungetc() 仅限于一个字符。

    编辑
    没有。看起来unget() 可以追溯到putback()

    【讨论】:

    • 并不是我在抱怨你完全合理的答案,但我认为它并没有真正回答这个问题。如果我用unget() 替换所有putback(character) 调用(其中character 保证是最后读取的字符),定义的行为是否相同?
    • 在我看来确实是这样。 putback() 使您能够放回除上次读取字符之外的其他内容。如果您只使用putback(last_read_character),效果与调用unget() 相同,但没有明确保证您确实“取消了”最后读取的字符。
    • 我最终还是使用了自定义流,它可以根据需要放回尽可能多的字符。
    【解决方案2】:

    这不是您可能期望的答案,但想介绍一下我的推理。文档中提到方法 putbackunget 分别调用 streambuf::sputbackcstreambuf::sungetc。定义如下:

    streambuf::sungetc

    将获取指针向后移动一个字符,使输入操作获得的最后一个字符再次可用于下一个输入操作。

    函数在运行过程中,如果get指针gptr指向与起始指针eback相同的位置,函数将调用受保护的虚成员函数pbackfail。

    另一个:

    streambuf::sputbackc

    get 指针被移回指向当前位置之前的字符,因此最后一个字符 c 再次变为可用,作为下一个输入操作在该位置读取的字符。

    在其运行期间,如果字符 c 与 gptr()[-1] 不匹配,或者如果 get 指针 gptr 指向与起始指针 eback 相同的位置,则函数调用受保护的虚拟成员函数 pbackfail。

    当 c 与该位置的字符不匹配时,如果可能,streambuf 中 pbackfail 的默认定义会将 c 作为在该位置提取的字符添加前面,但派生类可能会覆盖此行为。

    成员函数 sungetc 的行为方式类似,但不带任何参数

    sputbackc 调用pbackfail 如果字符不匹配,这意味着该方法必须检查值是否相等。看起来额外的检查是唯一的开销,但不知道它是如何在实践中解决的。我可以想象,如果最后一个字符未存储在对象中,则必须重新读取它,因此即使字符保证相同,您也可能会期望它。

    当我们打电话给unget时,我有点担心情况,但最后一个字符不可用。 putback 会正确输入值吗?我怀疑,但在对文件进行操作时不应该是这种情况。

    【讨论】:

    • 看起来不止一个区别。回退看起来像是前置?你确定它不会取代。考虑输入“ABC”,如果您读取 A,然后是 B,然后是放回 B,前置将插入并使输入流“ABBC”。这是真的吗?
    • @Xaade,这取决于实现,streambuf 默认什么都不做。 stringbuf 替换原始字符串中的字符(如果有写权限),但filebuf 仅替换内部缓冲区中的字符,因此不影响底层文件(但也会递减获取指针,因此没有插入新字符的效果)溪流)。规范中的更多详细信息:cplusplus.com/reference/iostream/streambuf/pbackfail.
    猜你喜欢
    • 2016-05-07
    • 1970-01-01
    • 2013-08-07
    • 2011-10-20
    • 2020-01-23
    • 1970-01-01
    • 1970-01-01
    • 2014-10-09
    • 2010-12-21
    相关资源
    最近更新 更多