【问题标题】:Do-while endlessly looping cout, ignores cinDo-while 无休止地循环 cout,忽略 cin
【发布时间】:2013-02-01 05:04:56
【问题描述】:

此程序在指定范围内打印指定数量的数字。但是,当我输入一个字符时,它只会无限循环我在其中执行的任何一个循环。例如:如果我在“输入最大数字”cin 中输入一个字符,它只会无休止地发送“输入最大数字”垃圾邮件,它只是跳过cin 并循环 cout(其他 2 个 do-while 也是如此。有人知道为什么吗?

#include <iostream>
#include <cmath>
#include <cstdlib>
#include <ctime>

using namespace std;

int roll(int mini, int maxi)
{
        int v = maxi - mini;
        int x  = mini + (rand() % (v+1));
        return x;

}
void caller()
{
    int a;
    int b;
    int c;

    do {
    cout << "Enter minimum number" << endl;
    cin.clear();
    cin >> a;
    } while (cin.fail());

    do {
    cout << "Enter maximum number" << endl;
    cin.clear();
    cin >> b;
    } while (cin.fail() || a > b);

    do {
    cout << "How many rolls?" << endl;
    cin.clear();
    cin >> c;
    } while (cin.fail());

    for (int i = 0; i < c; i++)
    cout << roll(a, b) << endl;
}

int main()
{
    srand (time(NULL));
    caller();
    return 0;
}

【问题讨论】:

  • 你从来没有真正提取字符。下次您尝试阅读某些内容时,它就会放在那里。
  • 我还是个初学者,你说的extract是什么意思?我该如何解决这个问题?
  • 由于你没有真正读过它,它还在流中,所以下次你尝试读任何东西时,它会是第一个读的东西,这又导致了问题。使用ignore 或其他东西来丢弃不可读的(至少对于int)字符。
  • 忽略仅在我放置一个字符一次时才有帮助。如果我第二次这样做,它只会再次循环。
  • 提示:忽略多个字符。实际上,对于键盘输入,只需忽略当前流中的所有字符即可。

标签: c++ infinite-loop do-while


【解决方案1】:

我不喜欢使用istream::fail() 进行循环控制。有关类似问题,请参阅 Why is iostream::eof inside a loop condition considered wrong?

相反,我依赖istream::operator &gt;&gt; 的返回值。

我还使用以下函数来重置标志并清除输入流上的输入:

void flush_stream(std::istream& stream)
{
    stream.clear();
    stream.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

有关更多信息,请参阅How do I flush the cin buffer?

所以我会这样编码你的输入检查:

int get_valid_number(const std::string& prompt)
{
    int number = 0;

    bool valid = false;
    while (!valid)
    {
        std::cout << prompt << std::endl;
        if (std::cin >> number)
        {
            valid = true;
        }
        flush_stream(std::cin);
    }

    return number;
}

希望将其提取到函数中的好处是显而易见的。 See it run.

【讨论】:

  • 虽然我更喜欢这种方式,但operator bool()operator void *() 使用fail() 来确定返回值。
【解决方案2】:

你可以尝试做类似的事情

int a;
string trash;

do {
  cout << "Enter minimum number" << endl;
  cin >> a;

  if(cin.fail()){
    cin.clear();
    cin >> trash;
  }

} while (cin.fail());

这将通过将 cin 流中的任何错误输入扔到 trash 字符串中来删除它。

此链接可以帮助您更好地理解这些cin 函数。

http://web.eecs.utk.edu/~cs102/lectures/cinLecture.html

【讨论】:

    猜你喜欢
    • 2016-12-24
    • 2013-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-04
    • 2023-02-15
    • 2013-06-05
    • 2021-12-30
    相关资源
    最近更新 更多