为什么在检查有效输入时我甚至会使用istream :: ignore?

时间:2012-04-11 00:03:09

标签: c++ windows istream

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背后的原因是什么(如果有的话)?

如果重要:
视窗
GCC
MinGW的

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

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