check integer
Apr 21, 2013 at 8:11am UTC
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 Apr 21, 2013 at 8:39am UTC
Apr 21, 2013 at 8:38am UTC
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 Apr 21, 2013 at 8:40am UTC
Apr 21, 2013 at 8:40am UTC
(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 && ...) )
Apr 21, 2013 at 9:05am UTC
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 ;
Apr 21, 2013 at 9:53am UTC
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;
}
Apr 21, 2013 at 12:55pm UTC
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;
Apr 21, 2013 at 1:03pm UTC
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 Apr 21, 2013 at 1:04pm UTC
Apr 22, 2013 at 12:09am UTC
@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.
Apr 22, 2013 at 12:19am UTC
EOF is not required to evaluate to -1, iirc.
Topic archived. No new replies allowed.