1

I need to check in my program if the user inputs an integer and not a character or string. Character isn't that bad since it's pratically an integer, but if the user enters a sequence of characters then it just goes nuts.

I've made this function

int* ask_lung(int* lung)
{
int tmp; // length of a word

cout << "Inserisci la lunghezza della parola da indovinare: ";
cin >> tmp;

if(cin)
{
    // Se i è uguale a o minore di 0 allora ritorna all'inizio

    if(tmp <= 0)
    {
        cout << endl << "\tNon puoi inserire 0." << endl << endl;
        ask_lung(lung);
    }
    else
    {
                    // the error is about here, when it reaches this part of the code it keeps showing the first line "Inserisci la lunghezza della parola da indovinare: "
        *lung = tmp;
    }
}
else ask_lung(lung);

return lung;
}
user229044
  • 232,980
  • 40
  • 330
  • 338
DomeWTF
  • 2,342
  • 4
  • 33
  • 46
  • What does this do/supposed to do ? – asheeshr Nov 30 '12 at 14:51
  • while( ! (cin >> myInt)){ std::cout << "Your input was not an int" << std::endl } Or i understand something wrong?! – demonking Nov 30 '12 at 14:52
  • if tmp is <= 0 or a character or a character sequence it should print an error and ask again for the input – DomeWTF Nov 30 '12 at 14:53
  • Why not do it in loop instead of doing it recursively? I.e. `while (!(cin >> tmp)) { /* Prompt user to enter a proper number */ }`. Also, if you don't want the number to be negative, declare `tmp` to be `unsigned`. – Some programmer dude Nov 30 '12 at 14:53
  • whith a while loop it just keeps showing the error i'm prompting like if the user was keeping typing wrong – DomeWTF Nov 30 '12 at 14:59

3 Answers3

2

In case of string of characters, your stream contains large number of invalid characters and you need to flush your stream of those characters to a new state. Instead of doing that recursively, it is better to do that in a loop. This would suffice for you reasonably.

while(true)
{
  cout << "Please Enter an Integer" << endl ;
  if (cin >> temp)  //true if a leading integer has entered the stream
    break ;
  else
  {
    cout << "Invalid Input" << endl ;
    cin.clear() ;
    cin.ignore(std::numeric_limits<streamsize> :: max(), '\n') ;
  }
}
Coding Mash
  • 3,338
  • 5
  • 24
  • 45
  • thank you, just as i thought i had to clean the stream, now it works just fine. – DomeWTF Nov 30 '12 at 15:03
  • can you explain me please cin.ignore(std::numeric_limits :: max(), '\n'); ? – DomeWTF Nov 30 '12 at 15:04
  • Do we need to handle the case of `12x` where the first part is an integer then there is some trash on the line? – Martin York Nov 30 '12 at 15:04
  • @DomeWTF: If you enter an invalid character that is not an integer it sets the bad bad (this is why you need to call clear()). But it does not remove the bad character from the stream so if you loop it will repeatedly try and read the bad character. So the ignore() calls reads and drops all characters until the new line character ('\n'). – Martin York Nov 30 '12 at 15:06
1

You can use std::all_of along with std::isdigit as:

std::string input;
std::cin >> input;

if ( std::all_of(input.begin(), input.end(), std::isdigit) )
{
     //input is integer
}

Or, if you want to test and also want the integer, then it is better to use input as int, as suggested by other answer. You may consider using std::stoi if you have (read) the string already. Note that std::stoi throws exception on error.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • That has different semantics than` operator>> int`. Your version checks if all characters to the next space are digits. The problem here one input may be packed (ie age followed by name). – Martin York Nov 30 '12 at 15:10
  • @LokiAstari:`1e3` is not an integer. – Nawaz Nov 30 '12 at 15:12
-2

The input is handled correctly, the problem is that you're returning a pointer to a local variable. That variable is on the stack, an it will be deallocated once the function returns. Instead you should just return the integer itself, not a pointer to it.

EDIT: I see that actually you're not returning a pointer to the integer, you're assigning to the integer that the pointer points to. Still, it's better to just return the integer itself.

user1610015
  • 6,561
  • 2
  • 15
  • 18