【问题标题】:cin input (input is an int) when I input a letter, instead of printing back incorrect once, it prints correct once then inc for the rest of the loopcin 输入(输入是一个 int)当我输入一个字母时,不是打印一次不正确,而是打印一次正确,然后在循环的其余部分中打印
【发布时间】:2018-05-18 01:57:58
【问题描述】:

我正在做一个乘法练习程序。正如我的标题所说,如果我在控制台中输入一个字母而不是数字,它会在第一个上说正确,但在其余部分上不正确。即使你不触摸键盘,它仍然会吐出错误的内容。

ans = table * i;
                    std::cout << table << " * " << i << " =" << std::endl;
                    std::cin >> input;
                    if(input == ans)
                    {
                            std::cout << "Correct! " << ans << std::endl;
                    }
                    else
                    {
                            std::cout << "Incorrect, the answer was " << ans << std::endl;
                            input = 0;
                            ans = 0;
                    }
            }

希望这能让您了解代码中发生的情况。这是输出。

Enter the table you'd like to learn.
5
Enter the amount of multiples
3
5 * 0 =
s
Correct! 0
5 * 1 =
Incorrect, the answer was 5
5 * 2 =
Incorrect, the answer was 10
5 * 3 =
Incorrect, the answer was 15

我能做些什么来解决这个问题?感谢您的输入

【问题讨论】:

  • anstableiinput都是ints,对吧?
  • 正确的@TheObscureQuestion,它们都是整数。
  • 发生匹配失败时,不再读取字符,输入的任何字符都留在输入缓冲区中(stdin未读只是等着在你的循环的下一次迭代中再次咬你 -- 除非你正确处理失败并考虑任何未读的字符

标签: c++ cin multiplication


【解决方案1】:

有多种方法可以构建各种测试,但是当使用cin(或通常使用任何输入函数)进行输入时,您必须考虑输入缓冲区中仍未读取的任何字符。使用cin,您必须验证三个条件:

  1. .eof() (eofbit) 已设置。输入结束,或者用户通过按 Ctrl+d 手动生成EOF(或在windoze上按Ctrl+z,但请参阅:CTRL+Z does not generate EOF in Windows 10 );

  2. .bad() (badbit) 已设置。发生不可恢复的流错误;和

  3. .fail() (failbit) 已设置。发生了匹配的或其他可恢复的故障。当失败发生时输入停止并且不再从输入缓冲区中提取字符

(您可以将 1 和 2 组合成一个测试,因为此时输入已经结束)

使用failbit,您必须做两件事。 (1) 您必须通过调用 cin.clear() 清除流错误状态,并且 (2) 您必须处理输入缓冲区中仍未读取的任何字符。通常这是通过包含&lt;limits&gt; 和调用来处理的:

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

(将从输入缓冲区中清除最多INT_MAX 个字符,当遇到分隔符(此处为'\n')时停止)

循环直到用户输入有效的 整数 的简短示例可能是:

#include <iostream>
#include <limits>

using namespace std;

int main (void) {

    int x = 0;

    while (1)       /* loop continually until valid input received */
    {
        cout << "\nenter an integer: ";
        if (! (cin >> x) ) {            /* check stream state */
            /* if eof() or bad() break read loop */
            if (cin.eof() || cin.bad()) {
                cerr << "(user canceled or unreconverable error)\n";
                return 1;
            }
            else if (cin.fail()) {      /* if failbit */
                cerr << "error: invalid input.\n";
                cin.clear();            /* clear failbit */
                /* extract any characters that remain unread */
                cin.ignore(numeric_limits<streamsize>::max(), '\n');
            }
        }
        else {  /* on succesful read of int */
                /* extract any characters that remain unread */
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            break;  /* then break read loop */
        }
    }

    cout << "integer: " << x << '\n';
}

(如开头所述,您可以通过多种不同的方式构建测试,只要您涵盖所有三个条件。)

此外,您可以通过调用rdstate() 来明确检查流位,而不是使用.fail() 等进行测试...,例如

if (std::cin.rdstate() == std::ios_base::failbit)

使用/输出示例

$ ./bin/cin_validate_int

enter an integer: no
error: invalid input.

enter an integer: "an integer"
error: invalid input.

enter an integer: abc 123
error: invalid input.

enter an integer: 123
integer: 123

查看一下,如果您还有其他问题,请告诉我。

【讨论】:

    【解决方案2】:

    当您执行cin &gt;&gt; input 并且它无法将输入解析为数字时,它会sets cin's failbit,而当设置failbit 时,它实际上不会再读取任何数据,直到您清除它。

    您应该通过调用cin.good() 来检查错误,并尝试使用cin.clear() 清除它们,但您不应该尝试清除某些错误(如EOF)而应该退出它们。

    【讨论】:

      猜你喜欢
      • 2021-07-03
      • 1970-01-01
      • 1970-01-01
      • 2020-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-25
      • 1970-01-01
      相关资源
      最近更新 更多