修复无限循环

时间:2017-09-30 11:57:01

标签: c++

我有一个代码,它从用户那里获取2个数字并检查输入是否等于或大于0,并检查输入是否为数字。

一切都很好,直到我用非数字值测试代码,例如"嗨"。

通过这样做,程序进入无限循环。

如果用户输入了错误的输入但是进入了一个不间断的循环,我希望代码请求另一个输入。

以下是代码:

#include <stdio.h>
#include <iostream>
#include <string>
#include <sstream>
#include <stdexcept>
using namespace std;

class Exp:public runtime_error
    {
        public:
            Exp(): runtime_error("input must be a numeric value equal or more than 0!\n")
            {
            }
    };

class GradeBook
{
    private:
        float number1,number2;
    public:
        GradeBook(float n1, float n2) : number1(n1), number2(n2)
        {
        }
        void setnumber1(float num1, int re1)
        {
            if(num1 >= 0 && re1)
                number1 = num1;
            else
                throw (Exp());
        }
        float getnumber1()
        {
            return number1;
        }
        void setnumber2(float num2, int re2)
        {
            if(num2 >= 0 && re2)
                number2 = num2;
            else
                throw (Exp());
        }
        float getnumber2()
        {
            return number2;
        }
};

int main()
{
    int result1, result2;
    float num1 = 0, num2 = 0;
    GradeBook myGradeBook(0, 0);

    reNum1:
    printf("Please enter number 1:\n");
    result1 = scanf("%f", &num1);
    try{
        myGradeBook.setnumber1(num1, result1);
    }
    catch(Exp exp)
    {
        cout<<exp.what();
        goto reNum1;
    }

    reNum2:
    printf("Please enter number 2:\n");
    result2 = scanf("%f", &num2);
    try{
        myGradeBook.setnumber2(num2, result2);
    }
    catch(Exp exp)
    {
        cout<<exp.what();
        goto reNum2;
    }
    return 0;
}

1 个答案:

答案 0 :(得分:1)

由于scanf行为,您的问题就发生了。调用scanf("%f")时,它会尝试从stdin读取一个浮点数。当用户输入Hi时,没有要读取的浮点数,因此scanf将不读取任何内容并返回0(填充了从stdin读取的数据的格式说明符数)。问题是输入仍然有未读的字符串Hi未决,因此下一次调用scanf("%f")将重复完全相同的操作。 您需要做的是“清除”stdin,以便用户可以输入新输入。这可以做到,即。通过在失败时调用getline

    try{
        myGradeBook.setnumber1(num1, result1);
    }
    catch(Exp exp)
    {
        string tmp;
        getline(cin, tmp);
        cout<<exp.what();
        goto reNum1;
    }

请注意,混合使用C风格的IO(scanf / printf)和C ++风格的IO(cout / cin)可能会降低性能。