While loop combined with input fail state loop

I am trying to run a while loop that has a range between 0 and 6 but if you input a character the while loop exits and the program goes into a fail state. I am looking for some help on how to combine the while loop with the range and the while loop that clears the fail state...If that makes any sense...

This is an assignment question.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    cout << "Enter percentage of salary contributed "
         << "to pension (0-6 percent): ";
    cin >> percentPention1;
    cout << endl;

    while (percentPention1 < 0 || percentPention1 > 6)
    {
        cout << "Invalid input, enter percentage of salary contributed to 
                 pension (0-6 percent): ";
        cin >> percentPention1;
        cout << endl;
    }

    while (cin.fail())
    {
        cin.clear(); //clear input stream
        cin.ignore(); //Ignore any text stored in buffer

        cout << "Invalid input, enter percentage of salary contributed to 
                 pension (0-6 percent): ";
        cin >> percentPention1;
        cout << endl;
    }
Last edited on
Doing numeric input with error handling in C++ is notoriously tricky. These are 2 general functions that will help. The first obtains an int value and deals with non-int input. The second uses the first to obtain a valid int within a specified range. Neither will return until a valid input is provided.

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
#include <string>
#include <limits>
#include <iostream>
#include <cctype>

int getInp(const std::string& prm) {
	const auto notsp { [&] {while (std::isspace(static_cast<unsigned char>(std::cin.peek())) && std::cin.peek() != '\n') std::cin.ignore(); return std::cin.peek() != '\n'; } };
	int n {};

	while ((std::cout << prm) && (!(std::cin >> n) || notsp())) {
		std::cout << "Invalid input. Not an int\n";
		std::cin.clear();
		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	}

	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	return n;
}

int getInp(const std::string& prm, int low, int upper) {
	int num {};

	do {
		num = getInp(prm);
	} while ((num < low || num > upper) && (std::cout << "Input not in range\n"));

	return num;
}

int main() {
	const auto percent { getInp("Enter percentage of salary contributed to pension (0-6 percent): ", 0, 6) };

	std::cout << percent << '\n';
}


main() shows an example of use. Any time you need an int input, you can use these functions.
Hi there, thank you for your response. The problem here is that i need to use the basic topics covered in our course and i am unfamiliar with some of the syntax used in these functions.
Ok. This is a simplified version - with less error checking:

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
#include <string>
#include <limits>
#include <iostream>

int getInp(const std::string& prm) {
	int n {};

	while ((std::cout << prm) && !(std::cin >> n)) {
		std::cout << "Invalid input. Not an int\n";
		std::cin.clear();
		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	}

	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	return n;
}

int getInp(const std::string& prm, int low, int upper) {
	int num {};

	do {
		num = getInp(prm);
	} while ((num < low || num > upper) && (std::cout << "Input not in range\n"));

	return num;
}

int main() {
	const auto percent { getInp("Enter percentage of salary contributed to pension (0-6 percent): ", 0, 6) };

	std::cout << percent << '\n';
}


To be even simpler,

 
std::numeric_limits<std::streamsize>::max()


could be replaced with a large constant - say 1000.

The rest of the code should be understandable.
Doing well behaved user numeric input is not a simple task. A tutorial (and example code) on "C++: Console User Input Done Right":

http://lb-stuff.com/user-input

MHS1986 wrote:
i need to use the basic topics covered in our course and i am unfamiliar with some of the syntax used in these functions.

Kinda hard to know what can and can't be used without telling us.

Learning other ways, better ways, to do things never hurts, though.
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
#include <iostream>
#include <concepts>
#include <string>

template < typename NUMBER > requires std::integral<NUMBER> || std::floating_point<NUMBER>
NUMBER get_number( const std::string& prompt, NUMBER minvalue, NUMBER maxvalue )
{
    std::cout << prompt << " [" << minvalue << ',' << maxvalue << "]: " ;
    NUMBER n = 0 ;
    if( std::cin >> n )
    {
        if( n >= minvalue && n <= maxvalue ) return n ;
        else std::cout << "error: out of range. " ;
    }
    else std::cout << "error: not a number. " ;

    std::cout << "try again.\n" ;
    std::cin.clear() ;
    std::cin.ignore( 1'000'000, '\n' ) ;
    return get_number( prompt, minvalue, maxvalue ) ;
}

int main()
{
    const int percent = get_number( "percentage of salary contributed to pension", 0, 6 ) ;
    std::cout << percent << '\n' ;

    const double score = get_number( "score", 0.0, 100.0 ) ;
    std::cout << score << '\n' ;
}
Topic archived. No new replies allowed.