1
\$\begingroup\$

I'm going through my C++ book and have currently made a working Guess The Number game.

The game generates a random number based on current time, has the user input their guess, and then tells them whether it was too high, too low, or the correct number.

The game functions fine if you enter a number, but returns 'Too High' if you enter something that is not a number (such as a letter or punctuation). Not only does it return 'too high', but it also continually returns it.

I was wondering what I could do to check if the guess, as input by the user, is an integer and if it is not, to return 'Not a number. Guess again.'

Here is the code.

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

int main()
{
    srand(time(0)); // seed the random number generator
    int theNumber = rand() % 100 + 1; // random number between 1 and 100
    int tries = 0, guess;

    cout << "\tWelcome to Guess My Number!\n\n";

    do
    {
        cout << "Enter a guess: ";
        cin >> guess;
        ++tries;

        if (guess > theNumber)
                cout << "Too high!\n\n";

        if (guess < theNumber)
                cout << "Too low!\n\n";

    } while (guess != theNumber);

    cout << "\nThat's it! You got it in " << tries << " guesses!\n";
    cout << "\nPress Enter to exit.\n";

    cin.ignore(cin.rdbuf()->in_avail() + 1);
    return 0;
}
\$\endgroup\$
0

4 Answers 4

2
\$\begingroup\$

Easiest is to use stringstream and check if conversion to int succeeded (reached eof)

#include "sstream"

//your code

cout << "Enter a guess: ";

std::string str;
cin >> str;
std::istringstream iss(str);
iss >> guess ;
if (iss.eof() == false)
    std::cout << "its not int";

//cin >> guess;
\$\endgroup\$
4
  • \$\begingroup\$ I tried c/ping the code and I am met with 'Enter your guess' but when I enter a numerical value it just goes to a blank line. Here's my do while loop. [Pastebin] pastebin.com/cjpCwiG5 \$\endgroup\$
    – FyrePlanet
    May 27, 2013 at 17:24
  • \$\begingroup\$ comment out "cin >> guess", I just added it there so you know which part of the code it changes, variable guess gets value from stringstream and stringstream gets value from default input (keyboard), so "cin >> guess" will not work after that, sorry for not being more clear in my post \$\endgroup\$
    – Lufi
    May 27, 2013 at 18:06
  • \$\begingroup\$ It's quite alright. However, it shows 'Too Low' after 'its not int'. I'm in Ch 3 of my C++ book (which deals with strings, for loops, and arrays) so hopefully I'll have a better understanding of how this will work when I'm through this chapter. -- For all intents and purposes, your answer and code did work for my question. Thank you. \$\endgroup\$
    – FyrePlanet
    May 27, 2013 at 18:15
  • \$\begingroup\$ An edit to my comment; I just added an else branch to if with the too high, too low stuff in a block. Works perfectly. Thanks again. \$\endgroup\$
    – FyrePlanet
    May 27, 2013 at 18:28
1
\$\begingroup\$

You're using an int variable, and the input is going directly into that, so if the input is not an integer, C++ tries to convert it to one. The user, on the other hand, can enter any string (or char array, technically?), whether it's an integer, a decimal number, or not a number at all.

For each of those three options:

  • If the input is an integer, things work as expected.
  • If the input is a decimal number, everything after the decimal is just dropped and you're left with the whole number before it. For example, typing in 2.34 will place the number 2 in the variable.
  • If the input is not a number, it looks like no change will be made to the variable. (I just had to run an experiment to test that.)

I recommend placing the input into a string variable, and then test if it's a number before converting it to an int for comparisons. As for how to check whether it's a number, I believe this has some good examples: How to determine if a string is a number with C++?

As an aside, since you did not initialize a value in the guess variable, if the user enters something other than a number, you will still have a junk value when the comparisons begin. See this quick example:

enter image description here

\$\endgroup\$
-1
\$\begingroup\$

Use sstringstream.

Try this:

using namespace std

string String;
cin >> String;
istringstream iss(String);
\$\endgroup\$
-1
\$\begingroup\$

This StackOverflow question covers it already. One of the suggestions there is this:

Use strtol, wrapping it inside a simple function to hide its complexity :

inline bool isInteger(const std::string & s)
{
   if(s.empty() || ((!isdigit(s[0])) && (s[0] != '-') && (s[0] != '+'))) return false ;

   char * p ;
   strtol(s.c_str(), &p, 10) ;

   return (*p == 0) ;
}

(Source)

I recommend asking pure programming questions like this at that site instead of this one.

\$\endgroup\$
0

Not the answer you're looking for? Browse other questions tagged .