# String problem with c++ game



## GSquadron (Sep 24, 2011)

Hi guys!
I am having a little problem with my latest game in c++
i know how to give an error if the user types in a wrong number,
but i dont know how to make it if the user types in a string!
Anyone can help?
This is the code of the error so far:

```
try
    {
        if (number < 1 || number > 9)
        {
            throw 1;
        }
    }
    catch(int x)
    {
        cout << "\n You typed a wrong number! ERROR: " << x << endl;
        game();
    }
```


----------



## GSquadron (Sep 24, 2011)

Tried this one:


```
try
    {
        if (number < z || number > a)
        {
            throw 1;
        }
    }
    catch(string x)
    {
        cout << "\n You typed a wrong number! ERROR: " << x << endl;
        game();
    }
```


----------



## Kreij (Sep 24, 2011)

I think you can use something like this ...

```
if (static_cast<int>(number) == number)
{
    // it's an integer
}
else
{
    // it's not an integer
}
```


----------



## GSquadron (Sep 24, 2011)

thanks 
Where did you get that command btw?
It sounds very logic to me


----------



## Kreij (Sep 24, 2011)

I'm not sure what you are asking. 
static_cast<> is a C++ operator.


----------



## GSquadron (Sep 24, 2011)

Never mind. Seems i can't find the real solution of the problem.
Yours does the same thing as the one i wrote 
Anyway, nice programming trick 
(i was asking where is the site where you learnt it)

The real problem is that if i type a char or string instead of a number, the game never ends restarting
I have this problem with all my games and this is the only thing i have not learned yet!
(i mean, fixing this problem, my games, will not have a single "bug")


----------



## ctrain (Sep 25, 2011)

Aleksander Dishnica said:


> Never mind. Seems i can't find the real solution of the problem.
> Yours does the same thing as the one i wrote
> Anyway, nice programming trick
> (i was asking where is the site where you learnt it)
> ...



cin is in the failure state and will just return immediately, you need to clear the fail state and wipe the input stream.

something like this:

```
int num;

std::cin >> num;
if(cin.fail())
{
	std::cout << "oh shit";
	
	std::cin.clear();							//clear the failure state
	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 	//clear the input stream
}

else
	...
```


----------



## GSquadron (Sep 25, 2011)

What should i put in this row when i have numbers from 1 to 10 for example?

```
cin.ignore(numeric_limits<streamsize>max(), '\n');
```


----------



## de.das.dude (Sep 25, 2011)

have you tried using the isdigit() function? 
header is ctype.h


----------



## GSquadron (Sep 25, 2011)

Same problem with the isdigit() lol
All things i have tried, all worked the same


----------



## de.das.dude (Sep 25, 2011)

LOL something is borked i guess. things like this happen.


----------



## Kreij (Sep 25, 2011)

Are you calling the game() method on a bad input?
That's what restarting the game, no?

If not, I'm confused.

Are you trying to do something like this?


```
While input does not equal the exit command
{
  Get input
  if (input is valid)
  {
      Do something with valid input and ask for next input
  }
  else
  {
      If (input does not equal the exit command)
      {
          Throw an error an error and ask for a valid input
      }
   }
}
```


----------



## GSquadron (Sep 25, 2011)

The problem is:
If the user types in a wrong integer like 3980218408.... 
that throws an error and the game goes back
If the user types in a string or char, that makes the game
restart infinitely
See the throw i have programmed in the first post

Also, your prototype is wrong as i don't mean to exit the game
The player could be anywhere, but if he doesn't press an integer
he looses the game and has to restart!


----------



## Kreij (Sep 25, 2011)

The pseudocode that I wrote would ask a player for input.
If the input was correct (valid) it would do something and then ask for the next input.
If the input was invalid, it would inform the player and then ask for input again.
If the player entered the "exit" string (whatever that may be) the game would quit.

Can you post your whole input code routine?


----------



## GSquadron (Sep 25, 2011)

```
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <fstream>
#include <string>
#include <ctype.h>

using namespace std;

int main()
{
    game();
}

int game()
{
    cin >> number;

    try
    {
        if (number < 1 || number > 7)
        {
            throw 1;
        }
    }
    catch(int x)
    {
        cout << "\n You typed a wrong number! ERROR: " << x << endl;
        game();
    }
```

This is all needed, cuz the whole programming is 600 lines
I don't really think you will find anything with the code anyway.


----------



## razaron (Sep 25, 2011)

Have you tried recursion*?

*Calling method x within method x.


----------



## GSquadron (Sep 25, 2011)

You mean like this?

```
catch(int x)
    {
        cout << "\n You typed a wrong number! ERROR: " << x << endl;
        game();
    }
```

It is "recursioned", i just deleted like 70 lines of code in the post
If i put a string or char, the recursion continues infinitely (or a double || float)


----------



## Kreij (Sep 25, 2011)

You don't want recursion in this case as you are just filling the stack and heap for no good reason. You should not call the game() method from within itself just for bad input.


----------



## GSquadron (Sep 25, 2011)

If i don't put the recursion, the game ends!


----------



## temp02 (Sep 25, 2011)

You really shouldn't call the game function again when some error occurs, you would be increasing the call stack for no valid/good reason, use *Kreij*'s approach and loop the game function call on main.
Also add "cin.clear();" to the catch, like so:

```
catch(int x)
{
  cout << "\n You typed a wrong number! ERROR: " << x << endl;
  cin.clear(); // flush the input error buffer
}
```


----------



## razaron (Sep 25, 2011)

How about having x be a *string *(instead of an *int*) then try to parse it into an *int*? If it doesn't parse it should go to the catch.

EDIT: by x I mean the number you're inputting.


----------



## Kreij (Sep 25, 2011)

If you "cin" to an integer, it will automatically go into a fail state (can't convert) as ctrain pointed out. You can use this to check to see if the inputted value is a string as opposed to an integer.

If the inputted integer is out of range, a simple range check will do.


----------



## GSquadron (Sep 25, 2011)

LOL
tried razaron's suggestion it works but ends in an unusual way!
I created 2 try functions, one with int x and one with char x


----------



## razaron (Sep 25, 2011)

Why and what 2 try functions?


----------



## GSquadron (Sep 25, 2011)

```
try
    {
        if (number < 1 || number > 7)
        {
            throw 1;
        }
    }
    catch(int x)
    {
        cout << "\n You typed a wrong number! ERROR: " << x << endl;
        game();
    }
try
    {
        if (number < 1 || number > 7)
        {
            throw 2;
        }
    }
    catch(char x)
    {
        cout << "\n You typed a wrong number! ERROR: " << x << endl;
        game();
    }
```


----------



## Kreij (Sep 25, 2011)

Try something like this.


```
int number;

int main()
{
    game();
}

void game ()
{
    bool valid_input = false;
    while (!valid_input)
    {
        valid_input = GetInput();
    }

    ... /// continue with game code
}

bool GetInput()
{
    cin >> number;
    if (cin.Fail())
    {
        // show error because it's a string
        return false;
    }
    else
    {
        if (number is < 0 || number > 9)
        {
             // show error becuase it's out of range
             return false;
        }
    }
    return true;
}
```


----------



## Kreij (Sep 25, 2011)

My C++ is a little rusty so please forgive any syntax problems.


----------



## GSquadron (Sep 25, 2011)

Still i get errors 
Don't get the bool programming, but i got your idea and it seems better than try
EDIT:LOL, so you made your errors by yourself ahahahaha anyway thanks 
I will try ti fix the errors


----------



## Kreij (Sep 25, 2011)

What errors and what other problems.
If you keep posting, I'll keep trying to help. 

bool (or Boolean) is just a type of variable (true or false).
I'm probably mixing C# and C++ code together. lol


----------



## GSquadron (Sep 25, 2011)

Errors:
a function-definition is not allowed here before '{' token|
expected '}' at end of input|
no return statement in function returning non-void|
||=== Build finished: 2 errors, 1 warnings ===|

I think you are mixing something.... maybe cheese with rice 

There are only 2 most awful errors ever.... parenthesis
One like this }
And one like this {

```
<o><o>
..L..
______
```
Help me!


----------



## ctrain (Sep 25, 2011)

Aleksander Dishnica said:


> What should i put in this row when i have numbers from 1 to 10 for example?
> 
> ```
> cin.ignore(numeric_limits<streamsize>max(), '\n');
> ```



You don't change anything, it was right in the first place.



Aleksander Dishnica said:


> The problem is:
> If the user types in a wrong integer like 3980218408....
> that throws an error and the game goes back
> If the user types in a string or char, that makes the game
> ...



I already answered it why it's restarting, clear the error and stream or parse everything as a string from the start.



temp02 said:


> You really shouldn't call the game function again when some error occurs, you would be increasing the call stack for no valid/good reason, use *Kreij*'s approach and loop the game function call on main.
> Also add "cin.clear();" to the catch, like so:
> 
> ```
> ...



cin.clear() doesn't clear the input stream, it will just try and clear the error state and the offending character is probably still there.


----------



## Kreij (Sep 25, 2011)

LOL ... I told you my C++ was a little rusty. Hard to write code without seeing the all the classes and the way you have everything set up.


----------



## GSquadron (Sep 25, 2011)

Still, i think there should be something to make it.
Like they do it in games. There must be something we
have not figured out yet. Or maybe programers don't
really want us to know....

I will let it like that for now, as i don't know what to do
What if the user enters 12k321j3.... ahahahaha


----------



## razaron (Sep 25, 2011)

I don't know c++ so here's my Java solution. It should be easy to convert to c++.

```
import java.util.*;

class test{
	
	public static void main(String args[]){
		game();
	}
	
	public static void game(){
		Scanner input = new Scanner(System.in);
		
		String userInput = input.nextLine();  //gets input from the user as a string.
		int inputAsInteger;
		
		if(checkInput(userInput)==true)
			inputAsInteger = Integer.parseInt(userInput);  //if "checker" from the checkInput() method is true for "userInput" parse it as an integer.
		else
			game(); //if not then start from the beginning.
		
		//carry on with the game() methods code using the variable "inputAsInteger" as the users input.
	}
	
	public static boolean checkInput(String x){
		boolean checker = false;
		
		try{
			int i = Integer.parseInt(x);
			checker = true;	//if the string does parse, checker will equal true.
		}
		catch(Exception e){
			checker = false;	//if the string does NOT parse, checker will equal false.
		}
		
		return checker;
	}
}
```

EDIT: why are my tabs so big and everyone else's so small?
EDIT2: I forgot to initialize "inputAsInteger". Make it initially equal to 0 and then it should work.


----------



## GSquadron (Sep 25, 2011)

After all.... you are not a beginner in java anymore 
Btw you tabs are equal as all
I hate java, since the last version.
Anyway, why the hell you return checker?
What i got from your statement is:
Sorry man, i cannot speak english, this is why i am speaking american 
If you don't know c++ how comes you programmed it in java?
Also, your program, if converted, the problem will persist for sure


----------



## razaron (Sep 25, 2011)

You have to return *checker* so your method knows which boolean to return (even though there's only one).
Also the program works. It keeps initializing game() until a correct input is given. I checked it by adding "*System.out.println(inputAsInteger);*" at the end of the game() method.
As for why in Java. That's because I managed to help you and understand your c++ code without knowing c++. Java and c++ are amazingly similar.

EDIT: I'm still a noob.


----------



## Kreij (Sep 25, 2011)

razaron said:


> EDIT: why are my tabs so big and everyone else's so small?



I use spaces for indents, not tabs in the code tags.


----------



## ctrain (Sep 25, 2011)

Aleksander Dishnica said:


> Still, i think there should be something to make it.
> Like they do it in games. There must be something we
> have not figured out yet. Or maybe programers don't
> really want us to know....
> ...



I showed how to handle it...


----------



## Kreij (Sep 25, 2011)

@Raz : Your Java code does a recursive call to game(). That is never something you want to do when error checking. Each time the game() method is called the calling method gets put on the stack as the recursive called method has to return to the calling method, so when the last game() call finaly completes it has to pop back through any game() method calls that called it.

Hope tht's not too confusing.


----------



## GSquadron (Sep 26, 2011)

ctrain said:


> I showed how to handle it...



Lol didn't get much attention


----------



## GSquadron (Sep 26, 2011)

Tried making a char or string value to the number instead of int, but still nothing new.
It works worse 
I tried another kind of programming of the exceptions like this:

```
int number = 0;

try
{
     cin >> number;
     
     if(number < 1 || number >7)
     {
           throw 200;
     }
}
catch(int e)
{
       cout << "\n You typed a wrong number! ERROR: " << e << endl;
}
catch(ios_base::failure&)
{
       cout << "\n You didn't type in a number!!" << endl;
}
catch(...)
{
       cout << "\n I don't know what happened" << endl;
}
```
Still the problem wont be fixed


----------



## ctrain (Sep 26, 2011)

save exceptions for... exceptional behavior, not something you can easily predict.


you can use stringstream for converting numerical types to strings and vice versa.


----------



## GSquadron (Sep 26, 2011)

I don't have to convert the int to string.
If i convert it, the user had already input the number


----------

