Prevent characters from being entered into int variable type

Hey,

so i spent all yesterday working on a ratio calculator for purchasing items. the program takes a given budget limit, takes a number of inputs (1-10) representing the value of an item being purchased, and tells you what same number of each item can be purchased for the given budget limit-

ie, you have 200k, you want to buy 3 items.

item x costs 89
item y costs 528
item z costs 111

the program calculates that you can purchase 274 of each item for a total expenditure of 200k.

the program works like it should and im just polishing it now.

problem is when the program requests the value of an item, if the user enters letters instead of numbers, the program dies instantly because that/those letters are being entered into an int variable.

is there any way to check if an input is numeric, or prevent users from entering non numeric inputs?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int infograb()
{

	for (int a = 0; a != Numberofratiovariables; a = a + 1)
	{

		cout << "please enter the name of item " << a + 1 << "." << endl;
		cin >> itemname[a];

		cout << endl << endl << "please enter the value of " << itemname[a] << "." << endl;
		cin >> value[a]; //here is where we're grabbing the item value. the variable value[a] is int type
		
		system("CLS");

	}

	system("CLS"); //looking back on this section of code, im thinking this cls is redundant

	return 0;

}


also, not related to the original question, but is there a forum here where i can dump my program code, or upload the compiled program for more experienced coders to look at, critique, and suggest ways that i might improve?
Last edited on
I'm sure someone else knows a better way but the only way I know is to read the line as a string and then check each value to see if it's 0-9. Once it passes the test, convert the string to int

cout << endl << endl << "please enter the value of " << itemname[a] << "." << endl;
cin >> value[a]; //here is where we're grabbing the item value. the variable value[a] is int type


you could try something like

1
2
3
4
5
6
7
8
9
int n;
cin>>n;
if(cin.fail()){
cout<<"Error message, try again";
cin>>n
}
else{
itemname[a]=n;
}

or something like that.
samuel, only problem with that is the entered values could be any where from 0 to infinity. would be alot of code to write to check all those numbers :P

d1g1, just tried your sugestion

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
 
int infograb()
{

	for (; counter != Numberofratiovariables;)
	{

		cout << "please enter the name of item " << counter + 1 << "." << endl;
		cin >> itemname[counter];

		cout << endl << endl << "please enter the value of " << itemname[counter] << "." << endl; 
		cin >> b;
		
		if (cin.fail())
		{
			system("CLS'");
			cout << "Please only enter numeric values for your item value." << endl << endl;
		}


		else
		{
			value[counter] = b;
			counter = counter + 1;
			system("CLS");
		}

	}

	system("CLS");

	return 0;

}


this also killed the program when i intentionaly entered a letter :(
add
1
2
3
4
5
6
7
		if (cin.fail())
		{
                   // cin.clear(); add these
                    //cin.ignore.
			system("CLS'");
			cout << "Please only enter numeric values for your item value." << endl << endl;
		}

and you can do a quick bounds check on your input if you need to keep it in a certain range
right after you capture with cin (if variable >= # || variable <=#)
i also found the page i was using a couple days ago for a similar problem https://stackoverflow.com/questions/18728754/checking-input-value-is-an-integer
Last edited on
success! works like a charm, no more infinite loops! now just need to add this into the other sections of code that require only numeric values. im gonna go ahead and mark this thread as resolved. thanks for the quick replies, very much appreciated!!!

heres the successful code for anyone else with the same issue:

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
int infograb()
{

	for (; counter != Numberofratiovariables;)
	{

		cout << "please enter the name of item " << counter + 1 << "." << endl;
		cin >> itemname[counter];

		cout << endl << endl << "please enter the value of " << itemname[counter] << "." << endl; 
		cin >> b;
		
		if (cin.fail())
		{
			cin.clear();
			cin.ignore();
			system("CLS");
			cout << "Please only enter numeric values for your item value." << endl << endl;
		}


		else
		{
			value[counter] = b;
			counter = counter + 1;
			system("CLS");
		}

	}

	system("CLS");

	return 0;

}
samuel, only problem with that is the entered values could be any where from 0 to infinity. would be alot of code to write to check all those numbers :P


The code would be pretty simple
This is pseudo code so a little more will be required

for (int i =0; i < stringEntered.size(); i++)
{
if ((stringEntered[i] greater than ascii 0 ) && (stringEntered[i] less than ascii 9 ) )
{// continue}
else
{// stop, not 0-9; // ask user for another INT}
}
// then of course convert string to int
Last edited on
s with this then are you checking each individual number or character of the entered value to to see if its between 0-9? i was thinking of it like check the whole value to make sure its a number, in which case i thought i would eseesntial need a loop to check through each number in a given range (1-1000, or w/e)each number in a given range. i.e.-

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
 

for (int i = 0; i != (rangemax + 1); i = i +1)
{

    if (enteredvalue == i)

    {

     cout << "its a number alright";
     i = (rangemax + 1);

    }

    else if ( i = range max)
    {

         if ( i != entered value)
        {
          cout << "invalid input, please try again";
          i = 0;
          t = value_entering_function();
        }

}


or something like that, if that makes any sence
Last edited on
In most cases, the best (simplest, most straight-forward) way to validate an input is to attempt the conversion and see if it succeeds.

You can do this directly on the input stream, or with the help of an auxillary stream.
e.g.: http://www.cplusplus.com/forum/general/195921/#msg941446

Consider setting the stream's exception mask to throw on irrecoverable input errors or the end-of-file character. This can simplify error handling, since you only have to concern yourself with malformed input (which merely sets failbit).

std::cin.exceptions(std::ios::badbit bitor std::ios::eofbit);

Last edited on
Topic archived. No new replies allowed.