-1

I'm trying to display "invalid option" when the user enters a letter instead of a number. I tried using the isalpha() function but I get an infinite loop showing 0 Invalid option!try again:. The 0 from the output is displayed when entering a letter. When I actually type in the number 0 the message is displayed and the loop is exited.

    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    #include <cctype>
    using namespace std;

    int main() {
        // Vaules do not change
        const int minNum = 1;
        const int maxNum = 100;
        int userInput;

        // Changes every second
        srand(time(0));

        // Random number is stored
        const int answer = minNum + (rand() % maxNum);
        cout << answer << endl; // For testing purposes

        cout << "Guess a number 1-100: ";
        cin >> userInput;
        cout << endl;

        if(userInput == answer) {
          cout << "Correct!\n\n";
        }
        while(userInput != answer) {
          if(userInput < 1 || userInput > 100 || isalpha(userInput))  {
            cout << userInput << " Invalid option!\ntry again: ";
            cin >> userInput;
            cout << endl;
          }
          else if(userInput < answer) {
            cout << userInput << " is too low!\ntry again: ";
            cin >> userInput;
            cout << endl;
          }
          else if(userInput > answer) {
            cout << userInput << " is too high!\ntry again: ";
            cin >> userInput;
            cout << endl;
          }
        }
        cout << userInput << " is correct!\n\n";
        return 0;
    }
Luis II
  • 17
  • 5
  • Hint: Since you're fetching into an `int` you'll never get alpha anything. – tadman Oct 23 '17 at 02:36
  • Possible duplicate of [Checking input value is an integer](https://stackoverflow.com/questions/18728754/checking-input-value-is-an-integer) – Amadeus Oct 23 '17 at 02:39
  • 1
    @tadman Thinking typecasting would work or fetching it into a char instead – Luis II Oct 23 '17 at 03:28

1 Answers1

1

When you need to deal with user input differently based on some logic, your best option is to:

  1. Read lines of text. Figure out what to do when there is no more input.
  2. Process each line of text using custom logic.

In your case, you could use:

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cctype>

using namespace std;

int main() {

   // Vaules do not change
   const int minNum = 1;
   const int maxNum = 100;
   int userInput;

   // Changes every second
   srand(time(0));

   // Random number is stored
   const int answer = minNum + (rand() % maxNum);
   cout << answer << endl; // For testing purposes

   std::string line;
   cout << "Guess a number 1-100: ";
   while ( getline(std:::cout, line ) )
   {
      // Deal with empty lines.
      if ( line.size() == 0 )
      {
         continue;
      }

      // If the first character is a letter ...
      if(isalpha(line[0]))  {
         cout << line << "\n Invalid option!\ntry again: ";
         continue;
      }

      // Extract the number from the line using a stringstream.
      // If there is a problem extracting the number ...
      std::istringstream str(line);
      if ( !(str >> userInput ) )
      {
         cout << line << "\n Invalid option!\ntry again: ";
         continue;
      }

      cout << endl;

      // Check the user input against the random answer.
      if(userInput == answer) {
         cout << "Correct!\n\n";
      }
      else if(userInput < 1 || userInput > 100 )  {
         cout << userInput << " Invalid option!\ntry again: ";
      }
      else if(userInput < answer) {
         cout << userInput << " is too low!\ntry again: ";
      }
      else if(userInput > answer) {
         cout << userInput << " is too high!\ntry again: ";
      }

      cout << "Guess a number 1-100: ";
   }
   cout << userInput << " is correct!\n\n";
   return 0;
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • I don’t understand what line is doing, is it reading what the user inputs? – Luis II Oct 23 '17 at 10:23
  • @lbonillaii, It reads a line of input. See http://en.cppreference.com/w/cpp/string/basic_string/getline for more info. – R Sahu Oct 23 '17 at 15:12
  • @R Sahu not sure why getline is not being recognized as a function throw xcode and compiling it with a make file. – Luis II Oct 24 '17 at 00:08
  • @lbonillaii, I don't know. I have never used xcode. searching for xcode and getline on SO reveals [some pertinent questions](https://stackoverflow.com/search?q=%5Bcpp%5D+xcode+getline). I hope one of them helps you resolve your problem. – R Sahu Oct 24 '17 at 04:13
  • I’m just going to rewrite it, for some reason it’s not recognizing it as a function even with the right library included – Luis II Oct 24 '17 at 12:32