Join 132,653 C++ Programmers for FREE! Get instant access to thousands of C++ experts, tutorials, code snippets, and more! There are 1,162 people online right now. Registration is fast and FREE... Join Now!
Is there a way that I can make the following code as a defualt and just calling the defualt each time I have and invalide input rather then placing this code after each input?
cpp
if (cin.fail()) { cout << "\n\nERROR: Invalid Input - Please enter a valid value.\n\n"; cin.get (); cin.clear(); // reset fail cin.ignore(1000, '\n'); // buffer clear return; // continue the loop }
I think you have a couple of lines in the wrong order. Unless I am mistaken, you should clear the error and the buffer and then get new input. Otherwise, you are going to clear whatever the user just put in.
Well sure... I can think of a few ways to do this (none of them are terribly easy).
what may be best is to just make an general input function that you use to get your input. Rather than try to change the behavior of cin.
Nick, I guess that I am not quit following your statement, can you maybe explain it a little further for me? I am really new to this so am a little lost. Thanks, Ken
Well you COULD make a manipulator or even extend an istream and make your own cin, you could even just overload the << operator. But All of these options are not "light weight".
What you CAN do pretty easily is make one or two input functions that add in this functionality:
cpp
#include <iostream> #include <string> #include <limits> using namespace std;
int getIntInRange(string prompt, int min, int max);
int main() { int val = getIntInRange("Please enter a value between 1 and 10", 1, 10); cout << "Value was: " << val << endl; getIntInRange("Enter any number", numeric_limits<int>::min(), numeric_limits<int>::max()); return 0; }
int getIntInRange(string prompt, int min, int max) { int retVal = 0; bool isNotGood = true; //true means the input is NOT valid! cout << prompt << ": "; do { cin >> retVal; if (!cin.good() || retVal < min || retVal > max) { cout << "\n!!! Please enter a number between " << min << " and " << max << " !!!" << endl; cin.clear(); //clear the status flag //ignore everything in the buffer up to (and including) // the first '\n' character. cin.ignore(numeric_limits<streamsize>::max(), '\n'); isNotGood = true; } else { isNotGood = false; // will cause us to exit the loop!! }
} while (isNotGood); return retVal; }
Edit: Just for the heck of it, you can use templates to generalize the function:
cpp
#include <iostream> #include <string> #include <limits> using namespace std;
template<class T> int getIntInRange(string prompt, T min, T max);
int main() { int val = getIntInRange<int>("Please enter a value between 1 and 10", 1, 10); cout << "Value was: " << val << endl; getIntInRange<double>("Enter any number", numeric_limits<double>::min(), numeric_limits<double>::max()); return 0; }
template<class T> int getIntInRange(string prompt, T min, T max) { int retVal = 0; bool isNotGood = true; //true means the input is NOT valid! cout << prompt << ": "; do { cin >> retVal; if (!cin.good() || retVal < min || retVal > max) { cout << "\n!!! Please enter a number between " << min << " and " << max << " !!!" << endl; cin.clear(); //clear the status flag //ignore everything in the buffer up to (and including) // the first '\n' character. cin.ignore(numeric_limits<streamsize>::max(), '\n'); isNotGood = true; } else { isNotGood = false; // will cause us to exit the loop!! }
} while (isNotGood); return retVal; }
This post has been edited by NickDMax: 16 Aug, 2008 - 06:08 PM
Nick, Thank you very much for your help, I will try these and see if I can make them work. I think that I will try the secound one like you suggested. Thanks, Ken
QUOTE(NickDMax @ 16 Aug, 2008 - 07:02 PM)
Well you COULD make a manipulator or even extend an istream and make your own cin, you could even just overload the << operator. But All of these options are not "light weight".
What you CAN do pretty easily is make one or two input functions that add in this functionality:
cpp
#include <iostream> #include <string> #include <limits> using namespace std;
int getIntInRange(string prompt, int min, int max);
int main() { int val = getIntInRange("Please enter a value between 1 and 10", 1, 10); cout << "Value was: " << val << endl; getIntInRange("Enter any number", numeric_limits<int>::min(), numeric_limits<int>::max()); return 0; }
int getIntInRange(string prompt, int min, int max) { int retVal = 0; bool isNotGood = true; //true means the input is NOT valid! cout << prompt << ": "; do { cin >> retVal; if (!cin.good() || retVal < min || retVal > max) { cout << "\n!!! Please enter a number between " << min << " and " << max << " !!!" << endl; cin.clear(); //clear the status flag //ignore everything in the buffer up to (and including) // the first '\n' character. cin.ignore(numeric_limits<streamsize>::max(), '\n'); isNotGood = true; } else { isNotGood = false; // will cause us to exit the loop!! }
} while (isNotGood); return retVal; }
Edit: Just for the heck of it, you can use templates to generalize the function:
cpp
#include <iostream> #include <string> #include <limits> using namespace std;
template<class T> int getIntInRange(string prompt, T min, T max);
int main() { int val = getIntInRange<int>("Please enter a value between 1 and 10", 1, 10); cout << "Value was: " << val << endl; getIntInRange<double>("Enter any number", numeric_limits<double>::min(), numeric_limits<double>::max()); return 0; }
template<class T> int getIntInRange(string prompt, T min, T max) { int retVal = 0; bool isNotGood = true; //true means the input is NOT valid! cout << prompt << ": "; do { cin >> retVal; if (!cin.good() || retVal < min || retVal > max) { cout << "\n!!! Please enter a number between " << min << " and " << max << " !!!" << endl; cin.clear(); //clear the status flag //ignore everything in the buffer up to (and including) // the first '\n' character. cin.ignore(numeric_limits<streamsize>::max(), '\n'); isNotGood = true; } else { isNotGood = false; // will cause us to exit the loop!! }
Yes I did find the post helpful, very. I am still trying to work it into my program, still trying to understand it all but looks great. Thanks Again, Ken
Nick, I am still trying to work this into my program, having a few problems though. I can edit it to fit my code okay, I think, but where do I put it? Here is my code:
using std::cin; using std::cout; using std::endl; using std::fixed; using std::setprecision; using std::setw; using namespace std;
class Mortgagecal { private: double Intyear; // interest rate per year public: double LoanAmt; // amount of the loan double Term; // term in years double NumMonths; // term converted to months double IntMonth; // interest converted to months double PaymentAmt; // variable for monthly payment double Balance; // running total double PrincipleAmt; // amount towards loan double AmtMortgage; // total amount to be paid back
void Get_Input()
{ while (1) //system("cls"); { // clears the screen system("cls"); cout << "Please enter a loan amount." << endl; cin >> LoanAmt; cout << endl;
if (cin.fail()) // no extraction took place { cout << "Please input a valid number" << endl; system("pause"); cin.clear(); // reset the state bits back to goodbit so we can use ignore() cin.ignore(1000, '\n'); // clear out the bad input from the stream continue; // try again }
cout << "Please enter the loan term in years." << endl; cin >> Term; cout << endl;
if (cin.fail()) // no extraction took place { cout << "Please input a valid number" << endl; system("pause"); cin.clear(); // reset the state bits back to goodbit so we can use ignore() cin.ignore(1000, '\n'); // clear out the bad input from the stream continue; // try again }
cout << "Please enter interest rate." << endl << "The amount must be in decimal format:" << endl; cin >> Intyear; cout << endl; if (cin.fail()) // no extraction took place { cout << "Please input a valid number" << endl; system("pause"); cin.clear(); // reset the state bits back to goodbit so we can use ignore() cin.ignore(1000, '\n'); // clear out the bad input from the stream continue; // try again } else { break; }
} // end while
//}
//void Amortization() { NumMonths = Term * 12; // Converts years to months IntMonth = Intyear/1200; // Converts annual rate to monthly rate PaymentAmt = (LoanAmt*IntMonth)/ (1-pow(1+IntMonth,-NumMonths));// Amortization formula } // end Amortization()
//void Print_Output() { cout << endl << "Based on your input..." << endl << "Your Monthly Mortgage Payment Amount will be: $ " << fixed << setprecision(2) // Displays amount to two decimal places << PaymentAmt << endl; // Displays the monthly payment system("pause"); } // end Print_Output()
} // end get
}; // end class Mortgagecal int main() { Mortgagecal mortCalc; // an object of the class Mortgagecal
char chIndicator = 'q'; // to quit or continue
do{ mortCalc.Get_Input(); if (!cin) // if any input from Get_Input() function is return 0; // invalid it will terminate the program cout << endl; // Next line cout << "Press 'q' to quit or any key to start over: "; cin >> chIndicator; // Reads input from user cout << endl;
}while ((chIndicator !='q') && (chIndicator != 'Q')); // end do loop
return 0; } // end main()
Thanks Again, Ken
QUOTE(tyserman474 @ 17 Aug, 2008 - 06:38 AM)
Nick, Thank you very much for your help, I will try these and see if I can make them work. I think that I will try the secound one like you suggested. Thanks, Ken
QUOTE(NickDMax @ 16 Aug, 2008 - 07:02 PM)
Well you COULD make a manipulator or even extend an istream and make your own cin, you could even just overload the << operator. But All of these options are not "light weight".
What you CAN do pretty easily is make one or two input functions that add in this functionality:
cpp
#include <iostream> #include <string> #include <limits> using namespace std;
int getIntInRange(string prompt, int min, int max);
int main() { int val = getIntInRange("Please enter a value between 1 and 10", 1, 10); cout << "Value was: " << val << endl; getIntInRange("Enter any number", numeric_limits<int>::min(), numeric_limits<int>::max()); return 0; }
int getIntInRange(string prompt, int min, int max) { int retVal = 0; bool isNotGood = true; //true means the input is NOT valid! cout << prompt << ": "; do { cin >> retVal; if (!cin.good() || retVal < min || retVal > max) { cout << "\n!!! Please enter a number between " << min << " and " << max << " !!!" << endl; cin.clear(); //clear the status flag //ignore everything in the buffer up to (and including) // the first '\n' character. cin.ignore(numeric_limits<streamsize>::max(), '\n'); isNotGood = true; } else { isNotGood = false; // will cause us to exit the loop!! }
} while (isNotGood); return retVal; }
Edit: Just for the heck of it, you can use templates to generalize the function:
cpp
#include <iostream> #include <string> #include <limits> using namespace std;
template<class T> int getIntInRange(string prompt, T min, T max);
int main() { int val = getIntInRange<int>("Please enter a value between 1 and 10", 1, 10); cout << "Value was: " << val << endl; getIntInRange<double>("Enter any number", numeric_limits<double>::min(), numeric_limits<double>::max()); return 0; }
template<class T> int getIntInRange(string prompt, T min, T max) { int retVal = 0; bool isNotGood = true; //true means the input is NOT valid! cout << prompt << ": "; do { cin >> retVal; if (!cin.good() || retVal < min || retVal > max) { cout << "\n!!! Please enter a number between " << min << " and " << max << " !!!" << endl; cin.clear(); //clear the status flag //ignore everything in the buffer up to (and including) // the first '\n' character. cin.ignore(numeric_limits<streamsize>::max(), '\n'); isNotGood = true; } else { isNotGood = false; // will cause us to exit the loop!! }
} while (isNotGood); return retVal; }
This post has been edited by NickDMax: 20 Aug, 2008 - 05:35 PM
Nick, I edited your program so it would work in my program, thanks. My problem now is that it does compile but it just goes to the end of the program and just alows me to enter Q to quit. Before I edited and put your program into mine it did run it and it went through all the options fine. Here is my code as is, maybe you can give me some ideas.
using std::cin; using std::cout; using std::endl; using std::fixed; using std::setprecision; using std::setw; using namespace std;
class mortgageCal { private: double intYear; // interest rate per year public: double loanAmt; // amount of the loan double term; // term in years double numMonths; // term converted to months double intMonth; // interest converted to months double paymentAmt; // variable for monthly payment double balance; // running total double principleAmt; // amount towards loan double amtMortgage; // total amount to be paid back
template<class T> double getIntInPut(T loanAmt, T term, T intRate);
//void Print_Output() { cout << endl << "Based on your input..." << endl << "Your Monthly Mortgage Payment Amount will be: $ " << fixed << setprecision(2) // Displays amount to two decimal places << paymentAmt << endl; // Displays the monthly payment system("pause"); } } }; template<class T> double getIntInPut(T amount, T term, T intYear) { double retVal = 0; bool isNotGood = true; //true means the input is NOT valid! //cout << prompt << ": "; do { cin >> retVal; if (!cin.good()) { cout << "\n!!! Please enter a valid number !!!" //<< amount << " and " << term << intRate<< " !!!" << endl; cin.clear(); //clear the status flag //ignore everything in the buffer up to (and including) // the first '\n' character. cin.ignore(1000, '\n'); isNotGood = true; } else { isNotGood = false; // will cause us to exit the loop!! }
} while (isNotGood); return retVal;
}
//}; // end class mortgageCal
int main() { mortgageCal mortCalc; // an object of the class mortgageCal
char chIndicator = 'q'; // to quit or continue
do {
//mortCalc.getIntInPut(loanAmt, term, intRate); if (!cin) // if any input from Get_Input() function is return 0; // invalid it will terminate the program cout << endl; // Next line cout << "Press 'q' to quit or any key to start over: "; cin >> chIndicator; // Reads input from user cout << endl;
}while ((chIndicator !='q') && (chIndicator != 'Q')); // end do loop
return 0; } // end main()
thnaks, Ken
QUOTE(tyserman474 @ 19 Aug, 2008 - 08:03 AM)
Nick, I am still trying to work this into my program, having a few problems though. I can edit it to fit my code okay, I think, but where do I put it? Here is my code:
using std::cin; using std::cout; using std::endl; using std::fixed; using std::setprecision; using std::setw; using namespace std;
class Mortgagecal { private: double Intyear; // interest rate per year public: double LoanAmt; // amount of the loan double Term; // term in years double NumMonths; // term converted to months double IntMonth; // interest converted to months double PaymentAmt; // variable for monthly payment double Balance; // running total double PrincipleAmt; // amount towards loan double AmtMortgage; // total amount to be paid back
void Get_Input()
{ while (1) //system("cls"); { // clears the screen system("cls"); cout << "Please enter a loan amount." << endl; cin >> LoanAmt; cout << endl;
if (cin.fail()) // no extraction took place { cout << "Please input a valid number" << endl; system("pause"); cin.clear(); // reset the state bits back to goodbit so we can use ignore() cin.ignore(1000, '\n'); // clear out the bad input from the stream continue; // try again }
cout << "Please enter the loan term in years." << endl; cin >> Term; cout << endl;
if (cin.fail()) // no extraction took place { cout << "Please input a valid number" << endl; system("pause"); cin.clear(); // reset the state bits back to goodbit so we can use ignore() cin.ignore(1000, '\n'); // clear out the bad input from the stream continue; // try again }
cout << "Please enter interest rate." << endl << "The amount must be in decimal format:" << endl; cin >> Intyear; cout << endl; if (cin.fail()) // no extraction took place { cout << "Please input a valid number" << endl; system("pause"); cin.clear(); // reset the state bits back to goodbit so we can use ignore() cin.ignore(1000, '\n'); // clear out the bad input from the stream continue; // try again } else { break; }
} // end while
//}
//void Amortization() { NumMonths = Term * 12; // Converts years to months IntMonth = Intyear/1200; // Converts annual rate to monthly rate PaymentAmt = (LoanAmt*IntMonth)/ (1-pow(1+IntMonth,-NumMonths));// Amortization formula } // end Amortization()
//void Print_Output() { cout << endl << "Based on your input..." << endl << "Your Monthly Mortgage Payment Amount will be: $ " << fixed << setprecision(2) // Displays amount to two decimal places << PaymentAmt << endl; // Displays the monthly payment system("pause"); } // end Print_Output()
} // end get
}; // end class Mortgagecal int main() { Mortgagecal mortCalc; // an object of the class Mortgagecal
char chIndicator = 'q'; // to quit or continue
do{ mortCalc.Get_Input(); if (!cin) // if any input from Get_Input() function is return 0; // invalid it will terminate the program cout << endl; // Next line cout << "Press 'q' to quit or any key to start over: "; cin >> chIndicator; // Reads input from user cout << endl;
}while ((chIndicator !='q') && (chIndicator != 'Q')); // end do loop
return 0; } // end main() [code]
Thanks Again, Ken
[quote name='tyserman474' date='17 Aug, 2008 - 06:38 AM' post='402236'] Nick, Thank you very much for your help, I will try these and see if I can make them work. I think that I will try the secound one like you suggested. Thanks, Ken
[quote name='NickDMax' post='402077' date='16 Aug, 2008 - 07:02 PM'] Well you COULD make a manipulator or even extend an istream and make your own cin, you could even just overload the << operator. But All of these options are not "light weight".
What you CAN do pretty easily is make one or two input functions that add in this functionality:[code=cpp]#include <iostream> #include <string> #include <limits> using namespace std;
int getIntInRange(string prompt, int min, int max);
int main() { int val = getIntInRange("Please enter a value between 1 and 10", 1, 10); cout << "Value was: " << val << endl; getIntInRange("Enter any number", numeric_limits<int>::min(), numeric_limits<int>::max()); return 0; }
int getIntInRange(string prompt, int min, int max) { int retVal = 0; bool isNotGood = true; //true means the input is NOT valid! cout << prompt << ": "; do { cin >> retVal; if (!cin.good() || retVal < min || retVal > max) { cout << "\n!!! Please enter a number between " << min << " and " << max << " !!!" << endl; cin.clear(); //clear the status flag //ignore everything in the buffer up to (and including) // the first '\n' character. cin.ignore(numeric_limits<streamsize>::max(), '\n'); isNotGood = true; } else { isNotGood = false; // will cause us to exit the loop!! }
} while (isNotGood); return retVal; }
Edit: Just for the heck of it, you can use templates to generalize the function:
cpp
#include <iostream> #include <string> #include <limits> using namespace std;
template<class T> int getIntInRange(string prompt, T min, T max);
int main() { int val = getIntInRange<int>("Please enter a value between 1 and 10", 1, 10); cout << "Value was: " << val << endl; getIntInRange<double>("Enter any number", numeric_limits<double>::min(), numeric_limits<double>::max()); return 0; }
template<class T> int getIntInRange(string prompt, T min, T max) { int retVal = 0; bool isNotGood = true; //true means the input is NOT valid! cout << prompt << ": "; do { cin >> retVal; if (!cin.good() || retVal < min || retVal > max) { cout << "\n!!! Please enter a number between " << min << " and " << max << " !!!" << endl; cin.clear(); //clear the status flag //ignore everything in the buffer up to (and including) // the first '\n' character. cin.ignore(numeric_limits<streamsize>::max(), '\n'); isNotGood = true; } else { isNotGood = false; // will cause us to exit the loop!! }
} while (isNotGood); return retVal; }
This post has been edited by NickDMax: 20 Aug, 2008 - 05:36 PM
I don't understand what you are trying to do. you have two main() you have the same function multiple times... multiple function definitions for the same function... basically your code will not compile because it is a mess!
CODE
//Includes tend to go at the top...
#include <iostream> //Dereference the namespace i.e. "using std::whatever" OR: using namespace std;
//declarations -- you MUST declare something before you use it. class SomeClass { private: int pvtData; public: SomeClass(int arg) : pvtData(arg) { }; int somePublicFunction(); }
//Again you have to DECLARE before you can use.... template<class T> double getIntInPut(T amount, T term, T intYear);
//Generally main tends to be the first function defined. This is because it is // the most important function in the file, and the entry point for // the program! int main() { //...SOME CODE...
return 0; }
//Now lets define the functions int SomeClass::somePublicFunction() { cout << "SomeData: " << pvtData; return ++pvtData; }
template<class T> double getIntInPut(T amount, T term, T intYear) { //... do stuff here ... return 0.0; }