Stringstream

hi, i am trying to check to see if the user is actually typing a valid number and not a letter or anything else so im using getline and then checking the data and transfering it to stringstream and then moving into an int variable. however when i output the int it gives me a crazy number that is not what i put in. any help would be appreciated.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
int SimulationUI::getInt(int min, int max)
{
	stringstream ss;
	string input;
	int output;
	bool fail;
	
	do
	{
		fail = false;
		getline(cin, input);
		
		while (isspace(input[0]))
			input = input.substr(1, input.length()-1);
			
		while (isspace(input[input.length()-1]))
			input = input.substr(0, input.length()-1);
			
		for (int i = 0; i < input.length(); i++)
		{
			if(!isdigit(input[i]))
				fail = true;
		}
		
		if (!fail)
		{
			ss << input;
			ss >> output;
				
			if (output < min || output > max)
				fail = true;
		}
		
		if (fail)
			cout << "Please type a digit between " << min << " and " << max << " >";
		else
			return output;
	} while (fail);	
}
You don't need to check the data before putting it into the stringstream, nor do you need to trim whitespace because the stream extraction operator >> does all that for you automatically, and it updates the state of the stream to a failure/bad state if the conversion fails.

stringstreams have an implicit cast to operator void* which can be used to indicate success-vs-failure (NULL for failure, non-NULL for success). Note, when a stream fails, you need to clear() its error flags before you can reuse it again.

All you really need to do to validate any conversion from a string is:
1
2
3
4
5
6
7
8
9
10
bool convert( const std::string& from, int& to )
{
    bool success( false );
    std::istringstream buffer( from );
    if ( buffer >> to )
    {
        success = true;
    }
    return success;
} 
You could actually make it a template, since it would work for other types too.

So all you should need to do when interacting with the user is something along these lines
1
2
3
4
5
6
7
    std::string input;
    std::getline( std::cin, input );

    int n;
    if( convert( input, n ) )
    {
    } 
(Deliberately excluding the while loop and min/max check to show the conversion usage)
Last edited on
Topic archived. No new replies allowed.