我的函数跳过了C ++中的循环参数

时间:2019-03-13 19:07:10

标签: c++ function loops infinite-loop

我的GetMark()函数,应该检查正确的范围,然后返回值,如果给定数组的正确性在参数超出可接受范围时被卡在无限循环中,则在添加之前SearchMark()函数可以正常工作,并且仅在用户最终输入给定范围内的值(0-100)之前循环,但是现在在给出第一个超出范围的值后,无论输入什么,它都会循环,我将非常感谢有什么建议么。完整代码:

int GetMark(int ModuleIndex) //user input function
{
    bool help;
    if (ModuleIndex < 0 || ModuleIndex >100)
    {
        help = false;
        while (help != true)
        {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            cout << "hey, that's a invalid value, try again!" << endl;
            GetMark(ModuleIndex);
            if ((ModuleIndex > 0) &&( ModuleIndex < 101))
            {
                help = true;
            }
        }
    }

    return ModuleIndex;
}

int SearchMark(int A[], int a) //search grades array for numbers of specific grades
{
    int i = 0;
    int ii = 0;

    while (i < 12)
    {
        if (A[i] == a)
            ii++;
        i++;
    }
    cout << "Mark " << a << " was found: " << ii << " times" << endl;
    return 0;
}



int main()
{
    int marks[12]; 
    int i = 0;
    int sum = 0;
    int grades[12];

    while (i < 12)
    {
        cout << "enter mark (0 - 100): " << endl;
        cin >> marks[i];
        GetMark(marks[i]);
        sum = sum + marks[i];
        if (marks[i] > 69)
        {
            grades[i] = 1;
        }
        else if (marks[i] > 59 && marks[i] < 70)
        {
            grades[i] = 2;
        }
        else if (marks[i] > 49 && marks[i] < 60)
        {
            grades[i] = 22;
        }
        else if (marks[i] > 39 && marks[i < 50])
        {
            grades[i] = 3;
        }
        else if (marks[i] < 35)
        {
            grades[i] = 4;
        }
        i++;
    }
    sum = sum / 12;
    cout << "your average is: " << sum  << endl;




    if (sum > 69)
    {
        cout << "You passed with 1st!" << endl;
    }
    else if ((sum > 59) && (sum < 70))
    {
        cout << "You passed with 2i!" << endl;
    }
    else if ((sum > 49) && (sum < 60))
    {
        cout << "You passed with 2ii!" << endl;
    }
    else if ((sum > 39) && (sum < 50))
    {
        cout << "You passed with 3rd!" << endl;
    }
    else if (sum < 40)
    {
        cout << "Your average is too low! You failed." << endl;
    }


    i = 0;
    while (i < 12)
    {
        if (marks[i] < 35)
        {
            cout << "Referred in module " << i + 1 << " mark too low." << endl;
        }
        i++;
    }

    SearchMark(grades, 1);
    SearchMark(grades, 2);
    SearchMark(grades, 22);
    SearchMark(grades, 3);
    SearchMark(grades, 4);

    return 0;
}`

5 个答案:

答案 0 :(得分:3)

该函数的功能过于复杂。只要在值不正确时循环,然后提示输入新值即可:

int GetMark(int ModuleIndex) {
    while (ModuleIndex < 0 || ModuleIndex > 100) {
        std::cout << "Invalid value.\n"
        std::cin >> ModuleIndex;
    }
    return ModuleIndex;
}

在理论分析中,递归非常方便,但是在实践中,这几乎总是一个错误。

答案 1 :(得分:1)

您需要允许用户在GetMarks中指定mark [i] / ModuleIndex的新值。清除cin后,从cin读取新值。您还需要返回该值,以便可以用该值而不是原始超出范围的值来更新main的标记[i]。

答案 2 :(得分:1)

很明显,在您getMark中,在while循环内,您以相同的无效getMark值递归调用ModuleIndex。因此,您需要在递归之前从标准输入中获取它。例如:

int GetMark(int ModuleIndex){
    bool help;
    if (ModuleIndex < 0 || ModuleIndex > 100){
        help = false;
        while (help != true){
                cout << "enter new ModuleIndex: \n";
                cin >> ModuleIndex;
                GetMark(ModuleIndex);
                // ...
        }

        return ModuleIndex;
    }

您的代码不可读,此外,您可以使用类std::vector

我建议测试以下代码:

int GetMarkIndex(const std::vector<double>& vMarks, const double Search) {
    auto beg{ vMarks.begin() }, end{ vMarks.end() };
    while (beg != end && *beg != Search)
        ++beg;
    return beg != end ? beg - vMarks.begin() : -1;
}

int main() {

    std::vector<double> marks(5);
    int value;

    auto i{ 0U };
    auto sz{ marks.size() };
    while (i != sz) {
        std::cout << "Enter marks 1-->100" << std::endl;
        if (cin >> value && value > 0 && value < 101) {
            marks[i] = value;
            ++i;
        }
        else
            std::cout << "Invalid input!" << std::endl;
    }

    for (auto e : marks)
        cout << e << ", ";
    std::cout << std::endl;

    double Search = 15;
    auto index{GetMarkIndex(marks, Search)};

    (index != -1) ? (std::cout << Search << " Found at index: " << index) : (std::cout << Search << " Not found!" << std::endl);


    std::cout << std::endl;
}

答案 3 :(得分:1)

基本上,您需要做的是从此方法中删除递归,而仅依赖while循环。无需调用该函数,而需要使用失败的输入再次提示输入,然后再次测试该值以退出循环。

int GetMark(int ModuleIndex) //user input function
{
    bool help;
    if (ModuleIndex < 0 || ModuleIndex >100)
    {
        help = false;
        while (help != true)
        {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            cout << "hey, that's a invalid value, try again!" << endl;
            cout << "enter mark (0 - 100): " << endl;
            cin >> ModuleIndex;
            if ((ModuleIndex > 0) &&( ModuleIndex < 101))
            {
                help = true;
            }
    }
}
    return ModuleIndex;
}

答案 4 :(得分:1)

您定义GetMark的方式和使用方式的结合是有缺陷的。

无论您在GetMark中做什么,在main中输入的值都不会改变。

GetMark更改为:

int GetMark()
{
   std::cout << "enter mark (0 - 100): " << std::endl;
   int mark;
   while ( std::cin >> mark )
   {
      if (  mark >= 0 && mark <= 100)
      {
         return mark;
      }

      std::cout << "Invalid value " << mark << std::endl;
      std::cout << "enter mark (0 - 100): " << std::endl;
   }

   // Unable to read.
   // Throw exception, or exit with an error message.
}

并更改其用法。代替

cout << "enter mark (0 - 100): " << endl;
cin >> marks[i];
GetMark(marks[i]);

使用

marks[i] = GetMark();

GetMark的工作版本:

int GetMark()
{
   std::cout << "enter mark (0 - 100): " << std::endl;

   std::string line;
   while ( getline(std::cin, line) )
   {
      std::istringstream str(line);
      int mark;
      if ( str >> mark )
      {
         if (  mark >= 0 && mark <= 100)
         {
            return mark;
         }
      }
      std::cout << "Invalid input: " << line << std::endl;
      std::cout << "enter mark (0 - 100): " << std::endl;
   }

   // Unable to read.
   // Throw exception, or exit with an error message.
   return 0;
}

Live Demo