Search code examples
c++loopsfor-loopwhile-loopfloating-point-exceptions

Where is the "floating point exception" error that occurs in my code?


Student programmer here. Every time I run my program the compiler terminates and says there is a floating point exception. Here is my code for reference:

#include <iostream>
#include <cmath>
#include <vector>
#include <cstdlib>
#include <string>
using namespace std;

int guesses = 3;
int quantity;
int discard_value;
vector<int> void_numbers(quantity);
int points = 10 + quantity * 5;
bool unique = 1;
int target = rand() % quantity + 1;

string check_guess(int guess)
{
  for (int i = 0; i < void_numbers.size(); i++)
    {
      if (guess == void_numbers[i])
        {
        return "You guessed a void number. You lose.";
        }
    }
  if (guess < target && guesses != 0)
  {
    return "Your guess is lower than the number.";
  }
  else if (guess > target && guesses != 0)
  {
    return "Your guess is higher than the number.";
  }
  else if (guess == target && guesses != 0)
  {
    return "You guessed the number. You win " + to_string(points) + " points.";
  }
  else if (guesses == 0)
  {
    return "You ran out of guesses. You lose.";
  }
  else
  {
    return "Invalid input. Please try again.";
  }
}


void test_input()
{
  cout << "How many void numbers would you like to add? (1-19): " << endl;
  while(invalidinput)
    {
      cin >> quantity;
      if (quantity < 1 || quantity > 19 || cin.fail())
      {
        cin.clear();
        cin.ignore();
        cin >> discard_value;
        cout << "Invalid input. Please try again." << endl;
      }
      else
      {
        break;
      }
    }
  while (void_numbers.size() < quantity)
    {
      int void_number = rand() % quantity + 1;
      for (int i = 0; i < void_numbers.size(); i++)
        {
          if (void_numbers[i] == void_number)
          {
            unique = 0;
            break;
          }

        }
      if (unique)
      {
        void_numbers.push_back(void_number);
      }
    }
  
  for (int i = 0; i < void_numbers.size(); i++)
    {
      for (int j = i + 1; j < void_numbers.size(); j++)
        {
          if (void_numbers[i] == void_numbers[j])
          {
            void_numbers.erase(void_numbers.begin() + j);
            j--;
            int temp_number = rand() % quantity + 1; 
            for (int i = void_numbers.size() - 1; i >= 0; i--)
              {
                if (void_numbers[i] == temp_number || void_numbers[i] == target)
                {
                  void_numbers.erase(void_numbers.begin() + j);
                }
              }
            }
          }
        }
  for (int i = 0; i < void_numbers.size(); i++)
    {
    cout << void_numbers[i] << endl; //currently have this here to test if the void numbers are being generated correctly
      cout << target;
    }
}
int main()
{
  srand(time(0));
  int quantity;
  int target = rand() % quantity + 1;
  char play;
  cout << "Welcome to the Numbers Game." << endl;
  cout << "1. In this game you have 3 guesses to guess a randomly-generated number between 1 and 20. The game will inform you if your guess is higher or lower than the random number." << endl;
  cout << "2. If you guess the number without running out of guesses, you receive 10 points. If you want more points, you have the option of inputting a quantity of void numbers." << endl;
  cout << "3. Void numbers make you instantly lose the game if you guess one of them, but each additional void number adds 5 additional points to your total score." << endl;
  cout << "4. If you use all your guesses and don't guess the number, you lose the game." << endl;
  test_input();
}

The overall program is a game in which the user guesses numbers. Before the game starts, the user can input a quantity of void numbers, numbers that will make the user lose the game if one of them are guessed. The test_input function is supposed to be used to generate numbers from 1 to whatever quantity the user wants (up to 19) in a vector without any repeating numbers. The numbers in the vector should also not match the number that is stored in the target variable.


Solution

  • Avoid global variables, really.

    int quantity;
    

    This is a variable definition without initializer. When it appears at block scope, the value of it would be indeterminate. Here instead we have it at file scope, and it is a global variable whose value is initialized to zero.

    int target = rand() % quantity + 1;
    

    This initializes another global variable target by calculating rand() % quantity +1. Since quantity is zero, you have integer division by zero, which is undefined behavior by the C++ standard and anything can happen. In your particular case, it may result in a division-by-zero floating point exception signal, but this is not guaranteed. Since this happens in the initialization of global variables (a special case of "static initialization"), the error occurs before main() is executed, and errors that come from static initializations are notoriously difficult to debug, which presents another good reason for avoiding globals.

    In general, you should avoid putting anything that is related to the logic of your program execution to the file or namespace scope. Those scopes are reserved for declarations. If for example you write int target; target = rand() % quantity + 1; instead of int target = rand() % quantity + 1; at the global scope, it won't compile at all.

    You should also get rid of the bad habit of using namespace std.