【问题标题】:Why do I have to press enter Twice?为什么我必须按两次回车?
【发布时间】:2012-11-25 23:52:14
【问题描述】:

由于某些原因,当我到达某个位置时,我必须按两次 Enter 才能提交。我添加了 clear 以防止它跳过输入,并添加了 ignore() 以防止它在缓冲区中保留任何额外的字符。我输入我的输入,然后它下降到一个新行,我再次点击 Enter 并输入输入并继续程序没问题,但我想知道为什么。这是一个代码sn-p:

    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.clear()cin.ignore(numeric_limits&lt;streamsize&gt;::max(),'\n')吗?
  • 如果我摆脱了两者并且用户超过了字符限制,那么我的程序就会崩溃。
  • 你要么自动输入回车,要么必须输入两次回车,绝对令人抓狂!

标签: c++ iostream


【解决方案1】:

在我看来,你扔了太多cin.ignore(),不知道为什么需要它们以及何时将它们放在那里。

有两种常见情况需要cin.ignore() 来“使输入正常工作”:

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

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

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

案例一:

cin.ignore() 如果您在执行 格式化输入 操作(即使用 @987654329 @运算符)。

这是因为&gt;&gt; 运算符将换行符留在输入缓冲区中;如果您只执行格式化的输入操作,这不是问题(默认情况下,它们会在尝试解释输入之前跳过所有空格),但如果之后您执行未格式化的输入,则会出现问题:getline 默认读取直到找到换行符,所以留下的“虚假换行符”会立即停止阅读。

所以,在这里你通常会调用cin.ignore(...) 来去掉你连续最后一次格式化输入操作之后的换行符,保证输入缓冲区是空的。之后,您可以直接调用getline,不用担心,因为您知道缓冲区是空的。

相反,将它放在任何getline 之前 是个坏主意,就像您在代码中所做的那样,因为可能存在导致getline 的代码路径输入缓冲区干净,因此ignore 调用将阻塞。

案例2:

istream 在格式化输入操作中遇到错误时,它会将“坏”字符留在缓冲区中,因此如果您重试该操作,您将无休止地卡住,因为违规者仍然存在。常用的clear()/ignore() 成语来拯救,从输入缓冲区中删除整个违规行。

同样,您不要随意放置clear()/ignore() 序列,而是仅在您从格式化输入操作(设置流的故障位)中获得输入错误之后。


现在,除了这些情况,很少使用cin.ignore()(除非你真的想跳过字符);不要随意散布“只是为了安全”,否则你会遇到你描述的问题。

【讨论】:

  • cin.ignore 的另一种情况是暂停控制台直到用户按下 Enter。
  • 对,我一直使用ignore() 的主要原因是忽略输入末尾的任何不需要的字符。如果我要求 1 个字符并且用户输入乱码,我只想提取那个字符。
【解决方案2】:

答案可以在here找到。

当 n 个字符被提取并丢弃或找到字符分隔符时,提取结束,以先到者为准。在后一种情况下,分隔符本身也被提取出来。

所以在你的情况下,程序在收到'\n' 字符之前不会继续。

【讨论】:

  • 查看我对下面帖子答案的评论。
【解决方案3】:

我认为cin.ignore(numeric_limits&lt;streamsize&gt;::max(), '\n'); 期望输入中的\n 并没有找到它,因此您必须再次按 Enter 才能找到它。

【讨论】:

  • 如果我在我的忽略中去掉'\n',它永远不会进入下一个输入,我只是继续按回车。
  • 只需评论该行,看看它是否有效://cin.ignore(numeric_limits&lt;streamsize&gt;::max(), '\n');
  • 如果我注释掉整行,那么它会混淆我的下一行输入。
  • 如果你用cin.get();代替cin.clear();cin.ignore(numeric...会怎样?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-16
  • 1970-01-01
相关资源
最近更新 更多