【问题标题】:Why would I even use istream::ignore when checking for valid input?为什么我在检查有效输入时还要使用 istream::ignore?
【发布时间】:2012-04-11 00:03:08
【问题描述】:

C++ FAQ over at parashift 使用类似于以下内容:

while (cout << "Enter an integer: " && !(cin >> foo))
{
    cin.clear();

    //feel free to replace this with just (80, '\n') for my point
    cin.ignore (numeric_limits<streamsize>::max(), '\n');
}

不过,cin.ignore (...) 似乎没有必要。为什么我不能只使用cin.sync()?它更短,不需要长度。它也更加通用,因为无论输入缓冲区中是否有任何字符,它都将以相同的方式工作。我已经在与ignore 相同的循环中测试过一次,它的工作方式相同。然而,似乎每个涉及此类输入验证的示例都使用ignore 而不是sync

当有更简单的替代方案时,使用 ignore 背后的原因是什么(如果有的话)?

如果重要的话:
窗户
海合会
MinGW

【问题讨论】:

    标签: c++ windows istream


    【解决方案1】:

    在 ifstream 上,sync() 的效果是实现定义的(根据 C++11,§27.9.1.5/19)——不能保证它会做你想做的事(也不能真正保证什么它会做的所有)。在典型情况下,当且仅当流被行缓冲时,它将大约相当于ignore——但如果流未被缓冲,它可能不会做任何事情,如果流被完全缓冲,它可能会做坏事。

    【讨论】:

    • 始终使用实现定义,呵呵。如果不是这样,我想这将是一个很好的候选人。
    • @chris:是的,如果它能可靠地做你想做的事,那么它会是做你想做的事的好人选。 :-)
    【解决方案2】:

    两者都做不同的事情。 sync 丢弃已经预读的字符,无论有多少,或者它们是什么。另一方面,ignore 会丢弃字符,直到遇到某个字符,无论这些字符是否已经被读取,或者是否还有更多字符已经提前读取。例如,假设cin 有一个 40 字节的缓冲区,但您的行有 80 个字节。然后很可能前 40 个字节已被读取到 cin 的缓冲区。在您解释了这些开头之后,通过调用sync,您将丢弃您已经阅读的那 40 个字符的其余部分,但不是中的其他 40 个字符线。另一方面,您的输入可能来自通常不进行行缓冲的管道。在这种情况下,您不仅可以丢弃当前行,还可以丢弃已预先读取的下一行的部分内容。 OTOH 与ignore 一起,你总是知道你总是会读到下一个\n(假设要忽略的最大字符数足以遇到它)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-16
      • 1970-01-01
      • 2020-05-13
      • 1970-01-01
      • 2015-11-26
      • 1970-01-01
      相关资源
      最近更新 更多