MORE RECURSION�W/ INPUT VALIDATION
A LECTURE FOR THE C++ COURSE
Each slide may have its own narration in an audio file. �For the explanation of any slide, click on the audio icon to start the narration.
The Professor‘s C++Course by Linda W. Friedman is licensed under a �Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
HERE’S WHERE WE WERE: FACTORIAL
#include <iostream>
using namespace std;
double factorial (int); //recursive factorial function
const int MIN = 0;
const int MAX = 30;
int main(){
int n;
do{
cout << "Enter an integer between " <<MIN<< " and " << MAX << ": ";
cin >> n;
}while (n < MIN || n > MAX); //Q: Can we use an ‘if’ instead?
cout << n << "! = " << factorial(n) << endl;
return 0;
}
double factorial (int x){
if (x <=1) return 1;
else return x * factorial (x-1); //Q: is the else needed?
}
RECURSION
2
ENHANCING THE PROGRAM
//recursive factorial function
//with some input validation
#include <iostream>
using namespace std;
double factorial (int);
int getInt();
const int MIN = 0;
const int MAX = 30;
int main(){
int n;
n = getInt();
cout << n << "! = " << factorial(n) << endl;
return 0;
}
int getInt(){
int number;
cout << "Enter an integer between " <<MIN<< " and " << MAX << ": ";
cin >> number;
while (number < MIN || number > MAX) { //Bad Data
cout << "\n\tThat number was incorrect." <<"\n\tPlease try again.\n" ;
cout << "\nEnter an integer between " <<MIN<< " and " << MAX << ": ";
cin >> number;
}
return number;
}
RECURSION
3
double factorial (int x){
if (x <=1) return 1;
else return x * factorial (x-1);
}
REFINING INPUT VALIDATION
Why do we insist that the user must continue to enter data indefinitely until the correct kind of data value is entered? Alternative: We can give the user options in a menu, either enter a data value, or quit. Another alternative, just accept data a certain number of times, the “three strikes and you’re out approach.” How to do that? Maybe something like this:
RECURSION
4
REFINING INPUT VALIDATION
int getInt(){
int number;
for (int i=1; i<=3; i++){
cout << "Enter an integer between " <<MIN<< " and "<< MAX << ": ";
cin >> number;
if (number < MIN || number > MAX) {
cout << "\n\tThat number was incorrect.“ <<"\n\tPlease try again.\n" ;
} //end ‘then’ block
else break;
} //end for loop
return number;
}
RECURSION
5
Problem: This function will return number even if it proved to be invalid. Let’s try again. Set up a flag that can be tested in main to determine whether the number is valid or not.
REFINING INPUT VALIDATION
int getInt(){
int number;
for (int i=1; i<=3; i++){
cout << "Enter an integer between " <<MIN<< " and "<< MAX << ": ";
cin >> number;
if (number < MIN || number > MAX) {
cout << "\n\tThat number was incorrect."<<"\n\tPlease try again.\n" ;
} //end ‘then’ block
else break;
} //end for loop
if (i>3) // test to see if for loop “ran through”
return 0; // valid data not entered
else
return 1; // data entered is valid
}
RECURSION
6
Problem: We now have a testable flag sent back to main() but we no longer have the number itself. It remains in the function’s domain. Let’s try to create a Boolean function with an output parameter, number.
REFINING INPUT VALIDATION
bool getInt(int number){
int i;
for (i=1; i<=3; i++){ //Scope: why not declare i in the loop?
cout << "Enter an integer between " <<MIN<< " and "
<< MAX << ": ";
cin >> number;
if (number < MIN || number > MAX) {
cout << "\n\tThat number was incorrect."
<<"\n\tPlease try again.\n" ;
} //end ‘then’ block
else break;
} //end for loop
if (i>3) // test to see if for loop “ran through”
return 0; // valid data not entered
else
return 1; // data entered is valid
RECURSION
7
Then in main():
...
if (getint(n)) // replaces n=getint() statement
cout << n << "! = " << factorial(n) << endl;
else
cout << “Sorry, we’ll do this another day.\n\n”
...
A Boolean function is one that returns a boolean value �[true (1) or false (0)].
THIS ALMOST WORKS
This ALMOST works. We will return to this problem shortly with a workable program.
RECURSION
8
MORE ABOUT BOOLEAN FUNCTIONS
//boolean.cpp
//modified from Hubbard ex 4.11 p.100
#include <iostream>
#include <ctype>
using namespace std;
void printCharCategory (char); //function prototype
void main() {
for (int c=0; c<128; c++) printCharCategory (c);
}//end main function
// Prints the category to which a given character belongs
void printCharCategory (char c) {
cout << "The character [" << c << "] is a ";
if (isdigit (c)) cout << "digit.\n";
else if (islower (c)) cout << "lower case letter. \n";
else if (isupper (c)) cout << "capital letter. \n";
else if (isspace (c)) cout << "whitespace character. \n";
else if (iscntrl (c)) cout << "control character. \n";
else if (ispunct (c)) cout << "punctuation mark. \n";
else cout << "Error.\n";
}//end printCharCategory function
RECURSION
9
LET’S TAKE A SHORT BREAK
RECURSION
10
Before continuing with this program, we must first learn about parameter passing in the course lecture on Functions & Data.
LET’S TAKE A SHORT BREAK
RECURSION
11
… and we’re back!
BACK TO FACTORIAL W/ INPUT VALIDATION
//recursive factorial function
//boolean input/validation function
//factorial.cpp
#include <iostream>
using namespace std;
double factorial (int);
bool getint (int&);
const int MIN = 0;
const int MAX = 30;
int main(){
int n;
if (getint(n))
cout << n << "! = " << factorial(n) << endl;
else
cout << "Sorry, we'll do this another day.\n\n";
cout << endl << endl;
return 0;
}
RECURSION
12
bool getint (int &number){�int i;
for (i=1; i<=3; i++){
cout <<"Enter an integer between " <<MIN<<" � and " <<MAX << ": ";
cin >> number;
if (number < MIN || number > MAX) {
cout << "\n\tThat number was incorrect."
<<"\n\tPlease try again.\n\n\n" ;
} //end 'then' block
else break;
} //end for loop
cout << endl;
if (i>3) // test to see if for loop "ran � through"
return 0; // valid data not entered
else
return 1; // data entered is valid
}
double factorial (int x){
if (x <=1) return 1;
else return x * factorial (x-1);
}
TO FACTORIAL W/ INPUT VALIDATION
RECURSION
13
REVIEW
RECURSION
14
What did we learn in this lecture? Plenty. Some terms to jog your memory: