繁体   English   中英

为什么我必须按两次输入?

[英]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()来“使输入正常工作”:

  1. 混合格式化和未格式化输入时;
  2. 从格式化输入错误中恢复。

在这两种情况下,您都希望从输入缓冲区中去除虚假字符; 如果没有任何这样的字符(这可能是你程序中发生的情况), cin.ignore()将暂停执行并等待用户输入 - 毕竟,你要求它忽略一些字符,该死的,它会服从它的命令。

(尽管默认情况下ignore()只会“吃掉”一个字符,无论它是什么,执行都会暂停直到找到换行符,因为默认情况下cin是行缓冲的 - 直到收到换行符才会检查新输入)

情况1:

如果您在执行格式化输入操作(即使用>>运算符)后执行未格式化输入操作(如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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM