[英]Why do I have to press enter Twice?
由于某些原因,当我到达某个位置时,我的程序必须按两次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');
有什么建议么?
在我看来,您在周围扔了太多cin.ignore()
,不知道为什么需要它们以及何时将它们放在那里。
有两种常见情况需要cin.ignore()
来“使输入正常工作”:
在这两种情况下,您都希望从输入缓冲区中去除虚假字符; 如果没有任何这样的字符(这可能是你程序中发生的情况), cin.ignore()
将暂停执行并等待用户输入 - 毕竟,你要求它忽略一些字符,该死的,它会服从它的命令。
(尽管默认情况下ignore()
只会“吃掉”一个字符,无论它是什么,执行都会暂停直到找到换行符,因为默认情况下cin
是行缓冲的 - 直到收到换行符才会检查新输入)
如果您在执行格式化输入操作(即使用>>
运算符)后执行未格式化输入操作(如getline
),则通常需要调用cin.ignore()
) 。
发生这种情况是因为>>
运算符在输入缓冲区中留下了换行符; 如果您只执行格式化输入操作(默认情况下,它们会在尝试解释输入之前跳过所有空格),这不是问题,但如果之后您执行无格式输入,这将是一个问题:默认情况下, getline
读取直到找到换行符,所以留下的“虚假换行符”将使它立即停止阅读。
因此,在这里您通常会调用cin.ignore(...)
调用以在您连续执行的最后一次格式化输入操作之后删除换行符,以确保输入缓冲区为空。 之后,您可以放心地直接调用getline
,因为您知道缓冲区是空的。
相反,将它放在任何getline
之前是一个坏主意,就像您在代码中所做的那样,因为可能存在导致输入缓冲区干净的getline
的代码路径,因此ignore
调用将被阻止。
当istream
在格式化输入操作中遇到错误时,它会将“坏”字符留在缓冲区中,因此如果您重试该操作,您将无休止地卡住,因为违规者仍然存在。 通常的clear()/ignore()
习惯用法可以解决问题,从输入缓冲区中删除整个违规行。
同样,您不会随机放置clear()/ignore()
序列,而是仅在您从格式化输入操作(设置流的 failbit)中获得输入错误之后。
现在,除了这些情况,很少使用cin.ignore()
(除非你真的想跳过字符); 不要“为了安全起见”随意散布它,否则您会遇到您描述的问题。
我认为cin.ignore(numeric_limits<streamsize>::max(), '\n');
期望在输入中有一个\n
但它没有找到它,所以你必须再次按Enter才能找到它。
可以在这里找到答案。
当提取并丢弃 n 个字符或找到字符 delim 时,提取结束,以先到者为准。 在后一种情况下,也会提取 delim 字符本身。
所以在你的情况下,程序将不会继续,直到收到一个'\n'
字符。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.