在我看来,你折腾太多了cin.ignore()
,不知道为什么需要它们以及何时将它们放在那里。
有两种常见情况cin.ignore()
需要“使输入正常工作”:
- 混合格式化和未格式化输入时;
- 从格式化的输入错误中恢复。
在这两种情况下,您都希望从输入缓冲区中删除虚假字符;如果没有任何这样的字符(这可能是您的程序中发生的情况),cin.ignore()
将暂停执行并等待用户输入 - 毕竟,您要求它忽略某些字符,该死的,它会服从它的命令。
(尽管ignore()
默认情况下只会“吃掉”一个字符,无论它可能是什么,执行都会暂停,直到找到换行符,因为默认情况下cin
是行缓冲的 - 在收到换行符之前不会检查新输入)
情况1:
cin.ignore()
如果您在执行格式化的输入操作(即使用运算符)之后执行未格式化的输入操作(如),则通常需要调用。getline
>>
发生这种情况是因为>>
操作员将换行符留在输入缓冲区中;如果您只执行格式化的输入操作,这不是问题(默认情况下,它们会在尝试解释输入之前跳过所有空格),但如果之后您执行未格式化的输入,则会出现问题:getline
默认情况下会读取直到找到换行符,所以留下“虚假换行符”将使其立即停止阅读。
因此,在这里您通常会在您cin.ignore(...)
连续执行的最后一个格式化输入操作之后调用 call 以摆脱换行符,从而保证输入缓冲区为空。之后,您可以放心getline
地直接调用,因为您知道缓冲区是空的。
相反,将它放在any之前getline
是一个坏主意,就像您在代码中所做的那样,因为可能存在导致getline
输入缓冲区干净的代码路径,因此ignore
调用将阻塞。
案例二:
当istream
在格式化输入操作中遇到错误时,它会将“坏”字符留在缓冲区中,因此如果您重试该操作,您将无休止地卡住,因为违规者仍然存在。通常的clear()/ignore()
习语来拯救,从输入缓冲区中删除整个违规行。
同样,您不会clear()/ignore()
随机放置序列,而是仅在您从格式化输入操作(设置流的失败位)中获得输入错误之后。
现在,除了这些情况之外,它并不常见cin.ignore()
(除非你真的想跳过字符);不要随意散布它“只是为了安全”,否则你会遇到你描述的问题。