W
W
walter732018-11-09 17:28:36
C++ / C#
walter73, 2018-11-09 17:28:36

Why does the program fall into an infinite loop for no reason and how to fix it?

There is the following code for a simple calculator. Attention to the question: why does it fall into an endless loop with knocking out an error when entering characters instead of numeric data in var1 and var2?
How can this be fixed?

// Калькулятор 0.3.1 

#include <iostream>
#include <conio.h>

// Прототип функции вывода справки
void fhelp (void);
// Прототип функции арифметических вычислений / размещения / возведения в степень
double arif (const double, const char, const double);
// Прототип функции сообщения об ошибке
void error (void);
// Прототип функции вычисления факториала
unsigned long long factorial (const unsigned int);
// Прототип функции выбора типа y/n
unsigned short answer (void);
// Прототип функции возведения в степень
double grade (const double, const int);
// Прототип функции извлечения квадратного корня
unsigned long square (const unsigned long long int);
// Прототип функции выбора между извлечением корня и нахождением факториала
void switch1 (unsigned long long, const char);

using namespace std;




int main()
{
  setlocale (LC_ALL, "Russian"); 		// установка языка	
  cout << "Здравствуйте! Это программа Калькулятор v0.3\nДля показа справки нажмите Y, для продолжения нажмите N...\n\n";
  
  while (1)	// Выбор показа справки
  {
    if (answer () == 2) 
    {
      fhelp ();
      break;
    }
    if (answer () == 3) break;
  }
  
  while (1)
  {
    double var1, var2; 	// переменные значений
    char operat; 		// оператор вычисления
    
    cout << "\n\nДля продолжения введите данные: ";
    cin >> var1;
    cin >> operat;
    
    if (operat == '!' || operat == '`')	// определение запроса функции вычисления факториала или нахождения квадратного корня и переход к ней
    {	
      if (var1 >= 0)
      {
        switch1 (var1, operat);
      }
      else 		
      error();
      continue;
    }
    
    cin >> var2;
    
    if (operat == '+' || operat == '-' || operat == '*' || operat == '/' || operat == '^' || operat == '~' || operat == '\\') 	// определение запроса функции арифметических действий / возведения в степень
    {																															// размещений / сочетаний и переход к ней 		
      arif (var1, operat, var2); 
      continue;
    }
    
    else 
    {
      error ();
      continue;
    }
    
  }
  
}



// Имплементация функции вывода справки
void fhelp (void)
{
cout << "\nС П Р А В К А:\n\nДля выполнения одного из простейших арифметических действий\nВведите два числа, разделяя их одним из символов: '+' '-' '*' '/''\n\nДля нахождения m в степени n введите m и n, разделяя знаком ^";
cout << "\nДля нахождения размещений из N по K без повторений, введите N и K, разделяя знаком ~\nДля нахождения сочетаний из N по K без повторений, введите N и K, разделяя знаком \\\n\n";
cout << "Для нахождения факториала числа введите число и знак !\nДля нахождения квадратного корня числа введите число и знак `\n";
}

// Имплементация функции арифметических действий / размещений/ сочетаний / возведения в степнеь
double arif (const double var01, const char var02, const double var03)
{
  switch (var02)
  {
    case '*':
    {
      cout << "\nПроизведение " << var01 << " и " << var03 << " равно: " << var01*var03;
      break;
    }
    case '/':
    {
      cout << "\nОтношение " << var01 << " к " << var03 << " равно: " << var01/var03;
      break;
    }
    case '+':
    {
      cout << "\nСумма " << var01 << " и " << var03 << " равна: " << var01+var03;
      break;
    }
    case '-':
    {
      cout << "\nРазность " << var01 << " и " << var03 << " равна: " << var01-var03;
      break;
    }
    case '^':
    {
      (int) var03;
      cout << "\nЧисло " << var01 << "в степени " << var03 << " равно: " << grade (var01, var03);
      break;
    }
    case '~':
    {
      if (var01 >= 0 && var03 >= 0 && var03 < var01)
      {
        (int) var01, var03;
        int var04 = var01 - var03;
        cout << "\nЧисло размещений из " << var01 << " по " << var03 <<" равно: " << (factorial(var01))/factorial(var04); 
      }
      else error(); 
      break;
    }
    case '\\':
    {
      if (var01 >= 0 && var03 >= 0 && var03 < var01)
      {
        (int) var01, var03;
        int var04 = var01 - var03;
        cout << "\nЧисло сочетаний из " << var01 << " по " << var03 <<" равно: " << (factorial(var01)/(factorial(var03)*factorial(var04))); 
      }
      else error(); 
      break;
  }
  }
}

// Имплементация функции вывода сообщения об ошибке
void error (void)
{
cout << "\nК сожалению, произошла ошибка, пожалуйста, попробуйте снова...\n";
}

// Имплементация функции вычисления факториала
unsigned long long factorial (const unsigned int fact)
{
  int f = fact;
  unsigned long long res = 1;
  
  if (fact == 0) return 1;
  while (f != 1)
  {
    res = f*res;
    --f;
  }
  
  return res;
}

// Имплементация функции выбора типа y/n
unsigned short answer (void)
{
  char ch; 
  ch = getch ();
  if (ch == 'y' || ch == 'Y') return 2;
  if (ch == 'n' || ch == 'N') return 3;
  else error();
  return 4;
}

// Имплементация функции возведения в степень
double grade (const double x, const int y)
{
  double var001 = x;
  int var002 = y;	
  unsigned short counter = 1;
  
  if (var002 > 0)
  {
    double helper = var001;
    while (counter != var002)
    {
      helper*=var001;
      ++counter;	
    }
    return helper;
  }
  
  if (var002 == 0)
    return 1;
  
  if (var002 < 0)
  {
    var002 = -var002;
    return (1/grade (var001, var002));
  }
}

// Имплементация функции извлечения квадратного корня
unsigned long square (const unsigned long long int num)
{
  unsigned long long num1 = num;
  unsigned long num2 = num1/2;
  while ((num2*num2) != num1 )
    {
      --num2;
      if (num2 < 2)
      {
        error ();
        return 0;
      }
      
    }
  return num2;
}

// Имплементация функции выбора между извлечением корня и нахождением факториала
void switch1 (unsigned long long num00, const char cho)
{
  unsigned long long var1 = num00;
  switch (cho)
  {
    case '!':
    {
      cout << "\nФакториал " << var1 << " равен: " << factorial(var1) << endl;
      break;
    }
    case '`':
    {
      cout << "\nКвадратный корень из " << var1 << " равен: " << square (var1);
      break;
    }
  }
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
Maxim Timofeev, 2018-11-09
@webinar

at least here:
while (counter != var002)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question