check integer

This checks for non numerical input but doesn't warn error when a double is entered. How can I correct this?

1
2
3
4
5
6
7
8
		while(ShapeChoice !=1 && ShapeChoice !=2 && ShapeChoice !=3 && ShapeChoice !=4)							
		{																		 
			cout <<"INVALID INPUT: Enter [1], [2], [3], [4] only."<<endl;					 				
			cin.clear();														
			cin.ignore();
			cin>>ShapeChoice;																											
		}
Last edited on
use a cast to turn the number to an integer then do your checks or do this:

1
2
3
4
5
#define isBetween(A,B,C) ( (A <= B ) && (B <= C) )
bool Accept(char shape)
{
   return isBetween('1', shape, '4');
}


1
2
while ( !Accept ( ShapeChoice ) )
...
Last edited on
(ShapeChoice != 1 || ShapeChoice != 2)

Try to evaluate this manually for a moment. If ShapeChoice is 1, then:
1
2
3
(1 != 1 || 1 != 2)
(false || true)
(true)


If ShapeChoice is 2, then:
1
2
3
(2 != 1 || 2 != 2)
(true || false)
(true)


If ShapeChoice is 3 (not 1 or 2), then:
1
2
3
(3 != 1 || 3 != 2)
(true || true)
(true)


There is no way that this expression can evaluate false. What you are looking for is the && operator:
while(cin.fail() || (ShapeChoice !=1 && ShapeChoice != 2 && ...) )
My code requires me to cin multiple user inputs. But if I enter a double, it doesn't warn an input error but thinks the digit after the decimal place is for the next input. How can I correct this?

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
int main()
{	
	cout.precision(3);															

	vector<Shapes*> PointShape;														
	vector<Shapes*>::iterator PointShapeIterator;											

	char RepeatCreateShape; 																												
	int Count(0); 

	cout<<"=================================================================="<<endl;
	cout<<"\t\t\t\tPolygons"<<endl;
	cout<<"=================================================================="<<endl;
	cout<<"This program enables the user to create 4 types of polygons."<<endl;
	cout<<"-->Polygons: Isosceles triangle, rectangle, pentagon, hexagon."<<endl; 
	cout<<"User may define polygon dimensions."<<endl;
	cout<<"User may modify polygons."<<endl;
	cout<<"-->Modifications: translation, rotation, Rescale."<<endl; 
	cout<<"User may create multiple polygons."<<endl;
	cout<<"==================================================================\n" <<endl;	 



	do 
	{																		
		int ShapeChoice(0);														
		char RepeatModification; 
		const int DivideZeroFlag(-1); 
		cout<<"Select shape [1] isoceles triangle, [2] Rectangle, [3] Pentagon, [4] Hexagon:"<<endl;
		cin>>ShapeChoice;

		while(cin.fail() || ShapeChoice !=1 && ShapeChoice !=2 && ShapeChoice !=3 && ShapeChoice !=4)							
		{																		 
			cout <<"INVALID INPUT"<<endl;	
			cout<<"Select shape [1] isoceles triangle, [2] Rectangle, [3] Pentagon, [4] Hexagon:"<<endl;
			cin.clear();														
			cin.ignore();
			cin>>ShapeChoice;																											
		}

		//==================================================================
		// Start switch case for shape creation
		//==================================================================	
		switch (ShapeChoice) 
		{
			//==================================================================
			// Triangle
			//==================================================================		
		case 1:
			{																		
				Count++;
				double Base(0);
				double Height(0);

				cout<<"Enter base length of triangle:"<<endl;
				cin>>Base;

				while(cin.fail() || Base <= 0) 									
				{	 
					cout<<"INVALID INPUT"<<endl;					
					cout<<"Enter base length of triangle:"<<endl;
					cin.clear();
					cin.ignore();
					cin>>Base;
				}

				cout<<"Enter height of triangle:"<<endl;
				cin>>Height;

				while(cin.fail()|| Height <= 0)										
				{
					cout<<"INVALID INPUT"<<endl;					
					cout<<"Enter Height of Triangle:"<<endl;
					cin.clear();
					cin.ignore();
					cin>>Height;
				}

				PointShape.push_back(new Triangle(Base, Height)); 
				cout <<"Vertex coordinates of shape "<<Count<<endl;
				PointShape[(Count-1)]->GetInfo();	
			}																		
			break; 
Instead of using cin >> value; I recommend you use getline(cin, value). While getline only supports getting a string you can then convert that string to an int and do a check to ensure it's not a double etc.

e.g.
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
40
41
#include <string>
#include <sstream>
#include <iostream>
#include <iomanip>

using namespace std;


bool converToInt(const string& value, int &result) {
	stringstream s(value);
	if ( !(s >> result) || s.peek() != (int)string::npos)
		return false;

	return true;
}


int main() {

	string user_input = "";
	int user_int = 0;

	cout << "Please enter your choice (q to quit): ";
	while(getline(cin, user_input)) {
		if (user_input == "q")
			break;

		if (user_input == "" || !converToInt(user_input, user_int)) {
			cout << "You choice of " << user_input << " was invalid." << endl;
			cout << "Please try again" << endl;

		} else {
			cout << "Yay! you entered " << user_int << endl;
		}

		cout << "Please enter another choice (q to quit): ";
	}

	cout << "Finished" << endl;
	return 0;
}
How can I make it so that when the input is 1,2,3 or 4, it doesn't have to go through the loop? At the moment, even when the user inputs the correct integer, it loops through so that the user has to input 'q' to progress.

Also, how can I prevent the user from progressing by entering 'q' when he doesn't enter 1,2,3, or 4?

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
	do 
	{						
		string ShapeChoice="";
		int ShapeChoiceInt(0);														
		char RepeatModification; 
		const int DivideZeroFlag(-1); 
		cout<<"Select shape [1] isoceles triangle, [2] Rectangle, [3] Pentagon, [4] Hexagon:"<<endl;

		while(getline(cin, ShapeChoice)) 
		{
			if (ShapeChoice == "q")
				break;

			if (ShapeChoice == "" || !converToInt(ShapeChoice, ShapeChoiceInt)) 
			{			
				cout << "INVALID INPUT" << endl;
				cout << "Select shape [1] isoceles triangle, [2] Rectangle, [3] Pentagon, [4] Hexagon:" << endl;
			} 
			else 
				if (ShapeChoice !="1" && ShapeChoice !="2" && ShapeChoice !="2" && ShapeChoice !="3" && ShapeChoice !="4" )
				{			
					cout << "INVALID INPUT" << endl;
					cout << "Select shape [1] isoceles triangle, [2] Rectangle, [3] Pentagon, [4] Hexagon:" << endl;
				} 
				else
				{
					cout << "You entered " << ShapeChoiceInt << endl;
					
				}

				cout << "Please enter another choice (q to quit): ";
		}

		cout << "Shape creation:" << endl;
Zaita wrote:
1
2
3
4
5
6
7
bool converToInt(const string& value, int &result) {
	stringstream s(value);
	if ( !(s >> result) || s.peek() != (int)string::npos)
		return false;

	return true;
}


What relationship does peek() have with string::npos? I would expect that to look more like:
1
2
3
4
5
6
7
8
9
10
bool converToInt(const string& value, int &result) {
    typedef std::istringstream in_stream ;

    in_stream s(value);

    if ( !(s>>result) || s.peek() != in_stream::traits_type::eof() )
        return false;

    return true;
}


Last edited on
@cire the return value form eof and string::npos are both -1 so the functionality is the same. Your way is more technically correct I would think, but as it is in C++ there are a million ways to write the same thing.
EOF is not required to evaluate to -1, iirc.
Topic archived. No new replies allowed.