出于某些原因,当我到达某个地点时,我必须按两次 Enter 才能让它提交。我添加了clear以防止它跳过输入和ignore()以防止它在缓冲区中保留任何额外的字符。我输入我的输入然后它下降到一个新行,我再次点击 Enter 然后输入输入并继续程序没有问题,但我想知道为什么。这是一段代码:
cin.ignore();
cout << "Enter Student Major (ex. COSC): ";
cin.getline(student.major, 6);
for(int i = 0; i < sizeof(student.major); i++)
student.major[i] = toupper(student.major[i]);
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
有什么建议吗?
答案 0 :(得分:7)
在我看来,你正在抛出太多cin.ignore()
左右,不知道为什么需要它们以及何时将它们放在那里。
有两种常见情况需要cin.ignore()
来“使输入正常”:
在这两种情况下,您都希望从输入缓冲区中删除虚假字符;如果没有任何这样的字符(这可能是你的程序中发生的事情),cin.ignore()
将暂停执行并等待用户输入 - 毕竟,你要求它忽略一些字符,并且该死的,它会服从它的命令。
(虽然ignore()
默认只会“吃掉”一个字符,无论它是什么,执行都会暂停,直到找到换行符,因为默认情况下cin
是行缓冲的 - 新输入不是检查,直到收到换行符)
cin.ignore()
),则通常需要 getline
次调用(即使用>>
运算符。
这是因为>>
运算符将换行符留在输入缓冲区中;如果您只执行格式化的输入操作(默认情况下它们在尝试解释输入之前跳过所有空格),这不是问题,但如果之后您执行无格式输入,则会出现问题:getline
默认情况下读取直到找到一个换行符,所以留下的“虚假换行符”将使其立即停止阅读。
因此,在这里,您通常会调用cin.ignore(...)
调用,以便在连续执行的最后一次格式化输入操作之后删除换行符,从而保证输入缓冲区为空。之后,您可以毫不畏惧地直接致电getline
,知道您将缓冲区留空了。
相反,将置于任何getline
之前是一个坏主意,正如您在代码中所做的那样,因为可能存在导致{{1}的代码路径输入缓冲区干净,所以getline
调用将阻塞。
当ignore
在格式化的输入操作中遇到错误时,它会在缓冲区中留下“坏”字符,因此如果您重试该操作,则会无休止地陷入困境,因为违规者仍然存在。通常istream
成语来拯救,从输入缓冲区中删除整个违规行。
同样,您不会随机地放置clear()/ignore()
序列,而只是在您从格式化输入操作(设置流的failbit)获得输入错误之后。
现在,除了这些情况之外,使用clear()/ignore()
并不常见(除非你真的想跳过字符);不要随意传播“只是为了安全”,因为否则你会遇到你描述的问题。
答案 1 :(得分:0)
我认为cin.ignore(numeric_limits<streamsize>::max(), '\n');
期望输入中有\n
并且找不到它,因此您必须再次按 Enter 才能找到它。< / p>
答案 2 :(得分:0)