validating my code

So I've got to a stage within my code where I'm looking at entering validation to ensure that it doesn't break and I'm hitting a dead end.

I'm looking at making my default in my switch loop round to bring back the menu// or just allow the user to enter a value(1-5).

Secondly I'm looking at not allowing letters to be entered within the following

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int getPos() 
	    {
	        int value;
	        cin>>value;
	
	        while(value<1 || value>8)
	        {
	            cout<<"out of range retry: ";
	            cin>>value;
	        }
	
	        return value;
    	}
	


would I be better off using an if else for this?

if(value > 0 && value < 9) - continue

else cout enter another value?
Last edited on
closed account (SECMoG1T)
if the user entered a char instead of an int an error will be set on the stream so you might need to reset the stream

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int getPos() 
{
      int value;
      std::cin>>value;
	
      while(value<1 || value>8 || !std::cin)
	{
              if(!std::cin) ///user entered a character e.5 'a' instead of an int
               {
                   std::cin.clear();
                   std::cin.ignore(1000,'\n');
               }

               std::cout<<"out of range \\ invalid input retry: ";
               std::cin>>value;
	}
	
       return value;
}


I'm looking at making my default in my switch loop round to bring back the menu// or just allow the user to enter a value(1-5).

i'd like to see your code for this but i'd suggest you make sure that, only correct input gets it way to your switch, that way you might avoid the "need to bring up the menu again"
Last edited on
Hello binaary,

For the most part I agree with Yolanda, but I would do two things different.

1. In the while condition I would use:((value < 1 || value > 8) && !std::cin). When using '!' in a condition && tends to work better. I also added a set of () around the lhs which may or mat not be needed.

2. When using "std::cin.ignore(...)" I like to use this version:
 
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );  // <--- Requires header file <limits>. 

Which is not to say that there is anything wrong with Yolanda's version. The only thing that should be in the input buffer is a '\n'.

The only other thing I would do is stay in the function until a valid input was achieved before returning that input.

Hope that helps,

Andy
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
#include <iostream>

int getPos()
{
    // avoid magic numbers
    const int MINV = 1 ;
    const int MAXV = 8 ;

    std::cout << "enter position [" << MINV << '-' << MAXV << "]: " ;
    int pos ;

    if( std::cin >> pos ) // if the user entered an integer
    {
        if( pos >= MINV && pos <= MAXV ) return pos ; // return valid value, within range

        else std::cout << "value is out of range. try again\n";
    }

    else // user did not enter an integer. input failed
    {
        std::cout << "non-numeric input. try again\n";
        std::cin.clear(); // clear the failed state of std:cin
        std::cin.ignore( 1000,'\n' ); // and throw the bad input away
    }

    return getPos() ; // try again
}
closed account (SECMoG1T)
@Andy hello while condition I would use:((value < 1 || value > 8) && !std::cin). When using '!' in a condition && tends to work better.

please note: the condition ((value < 1 || value > 8) && !std::cin) will not work properly , i mean
the function will never enter the loop if value<1 or value>8, the function will just return even if value == 20,-1,-19, check the condition's truth table.

what he/she needs is ((value < 1 || value > 8) || !std::cin)



+JLBorges approach.

Last edited on
@Yolanda,

I will have to work something up and give it a try with all ||s.

It has been my experience that '!' something tends to work better with && or maybe that is more with '!='.

I do like JLBorges's example too. They are always good.

Andy
I want to point out that this is a perfect example of a loop with the exit condition in the middle. Don't be afraid to code it this way. Here is JLBorges's excellent recursive solution recoded as a loop to demonstrate:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// avoid magic numbers
const int MINV = 1 ;
const int MAXV = 8 ;

int pos ;

while (true) {  // loop exits from break below
    std::cout << "enter position [" << MINV << '-' << MAXV << "]: " ;

    if( std::cin >> pos ) { // if the user entered an integer
	if( pos >= MINV && pos <= MAXV ) break ; // return valid value, within range

	else std::cout << "value is out of range. try again\n";
    } else { // user did not enter an integer. input failed
	std::cout << "non-numeric input. try again\n";
	std::cin.clear(); // clear the failed state of std:cin
	std::cin.ignore( 1000,'\n' ); // and throw the bad input away
    }
}

// pos is now a valid number 


closed account (SECMoG1T)
@Andy, I will have to work something up and give it a try with all

as for me well, when working with logic operators, if i find the result to an operation confusing then i like boiling everything down to a simple truth table,
that way what was confusing becomes obvious.

its good that we are always learning here, seeing different approaches to stuff its great, @JLBorges n @DHyden great approaches there.
cheers for the replies I'll take a look at them .

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
	switch (selection)
	{
	case 1:
		cout << "Play Beginner Game\n";
		cout << "\n";
		system("CLS");

		break;

	case 2:
		cout << "Play Intermediate Game\n";
		cout << "\n";
		system("CLS");

		break;
	case 3:
		cout << "Play Advanced Game\n";
		cout << "\n";
		system("CLS");

		break;

	case 4:
		cout << "Show Score Board\n";
		cout << "\n";
		break;

	case 5:
		cout << "Goodbye.\n";
		break;

	default: cout << selection << "is not a valid menu item.\n";

		cout << endl;
	}


is my switch. just having trouble making it loop back around if anything other than 1-5 is input.

While I'm on about my switch case, if I was to have a file for each of the different settings could I call each one within the corrispoding selection?
Last edited on
You want to exit when selection == 5, so do this:
1
2
3
4
5
6
do {
    ...
    switch(selection) {
    ....
    }
} while selection != 5);

Topic archived. No new replies allowed.