I'd like to catch exception which occurs when somebody gives not a number value on the cin so the program will read next value.
#include <iostream>
using namespace std;
int main()
{
int x = 0;
while(true){
cin >> x;
cout << "x = " << x << endl;
}
return 0;
}
If you really want to use exception handling, you could do something like this:
cin.exceptions(ios_base::failbit); // throw on rejected input
try {
// some code
int choice;
cin >> choice;
// some more code
} catch(const ios_base::failure& e) {
cout << "What was that?\n";
break;
}
Reference: http://www.cplusplus.com/forum/beginner/71540/
There is no exception being thrown at all. Instead, cin sets a "bad input" flag of sorts. What you want is this:
while ((std::cout << "Enter input: ") && !(std::cin >> x)) {
std::cin.clear(); //clear the flag
std::cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n'); //discard the bad input
std::cout << "Invalid input; please re-enter.\n";
}
This series of questions explains it really well.
Links:
clear()
ignore()
Add something like:
if(cin.fail())
{
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(),' ');
cout << "Please enter valid input";
}
int main()
{
int x = 0;
cin.exceptions(ios::failbit);
while(true){
try
{
cin>>x;
}
catch(ios_base::failure& e)
{
//..
}
cout<<"x = "<<x<<endl;
}
return 0;
}
This should work.
Related
I'm trying to make do while loop what will validate data! When wrong data got should ask again. BUT when wrong data got program do loop again with skipping cin >> a;
Here two validation codes what I already tried:
1st one [Pic of console]
int a;
do
{
a = NULL;
cout << "Press some number: ";
cin >> a;
} while (a>=0 || a<=0);
2nd one: [Pic of console]
int a;
do
{
cin.clear(); cin.sync();
cout << "give me number: "; cin >> a;
} while (cin.fail());
This way you can check input is number or not:
int a;
bool flag=false;
while (true)
{
flag=false;
std::string input;
std::cout << "Press some number: ";
std::getline(std::cin,input);
try
{
a = stoi(input);
}
catch(const std::exception& e)
{
std::cout <<"Invalid number" << std::endl;
flag=true;
}
if (!flag)
break;
There are other ways to do this but i didn't mess your head with vectors or other things.
I have a program that requires a user to input a integer number which then has to go to several conditions. When I run the program, if i input a int number it works but if i input a character, the programs just spams the error messages.
I think exception handling might work here but i m not sure how to do.Help out guys!
Here is a part of my prog:
#include <iostream.h>
#include <conio.h>
int i, j, data;
void main()
{
int tempdata;
retry:
cout<<"\n\n Enter the row and coloumn where you want to enter data" <<endl;
cin>>i>>j;
if (i>=1 && i<=9 && j>=1 && j<=9)
{
cout<<"\n Enter your desired value to put in that place"<<endl;
cin>>tempdata;
if(tempdata>=1 && tempdata<=9)
{
data=tempdata;
}
else
{
cout<<"\n Soduku contains numbers from 1 to 9 only.Please try again"<<endl;
goto retry;
}
}
else
{
cout<<"\nEntered row or coloumn is not valid"<<endl;
cout<<"Please try again"<<endl;
goto retry;
}
getch();
}
Instead of a cout, you should indeed use exception handling.
if(tempdata>=1 && tempdata<=9)
{
data=tempdata;
}
else
{
throw std::runtime_error("Soduku contains numbers from 1 to 9 only.Please try again");
}
By putting all this into a function, and not your main, you can then call this function within a try/catch block, and deal properly with the exception: display a pop-up message if you have a GUI, ignore the input, etc. The important part is that, if you ignore it, it is not actually ignored. It is dealt with. Which makes your code a LOT cleaner and maintainable. Example:
try
{
input();
}
catch(std::runtime_error& e)
{
// deal with your invalid input here
}
Also, goto statements are considered bad practice. They can be easily replaced by if/else or while statements, or with return codes in functions. And using them tend to make the code unreadable, difficult to follow.
You need to validate that cin >> is successful before you can then use the value entered. If the user enters data that does not match the expected type, you have to clear the error before you can read new input again.
Try this:
#include <iostream>
#include <limits>
int i, j, data;
bool isNumValid(int data) {
return ((data >= 1) && (data <= 9));
}
void clearInput() {
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
int main() {
int tempdata;
do {
std::cout << "\n\n Enter the row and column where you want to enter data" << std::endl;
if (!(std::cin >> i >> j)) {
std::cout << "\n Please enter numbers only!" << std::endl;
clearInput();
continue;
}
if (!isNumValid(i) || !isNumValid(j)) {
std::cout << "\nEntered row or column is not valid" << std::endl;
std::cout << "Please try again" << std::endl;
continue;
}
std::cout << "\n Enter your desired value to put in that place" << std::endl;
if (!(std::cin >> tempdata)) {
std::cout << "\n Please enter a number only!" << std::endl;
clearInput();
continue;
}
if (!isNumValid(tempdata) {
std::cout << "\n Soduku contains numbers from 1 to 9 only" << std::endl;
std::cout << "Please try again" << std::endl;
continue;
}
data = tempdata;
}
while (true);
std::cin.get();
return 0;
}
Alternatively:
#include <iostream>
#include <limits>
#include <stdexcept>
int i, j, data;
bool isNumValid(int data) {
return ((data >= 1) && (data <= 9));
}
void checkRowColValid(int row, not col) {
if (!isNumValid(row) || !isNumValid(col))
throw std::out_of_range("Entered row or column is not valid");
}
void checkDataValid(int data) {
if (!isNumValid(data))
throw std::out_of_range("Soduku contains numbers from 1 to 9 only");
}
int main() {
int tempdata;
std::cin.exceptions(std::ios_base::failbit);
do {
try {
std::cout << "\n\n Enter the row and column where you want to enter data" << std::endl;
std::cin >> i >> j;
checkRowColValid(i, j);
std::cout << "\n Enter your desired value to put in that place" << std::endl;
std::cin >> tempdata;
checkDataValid(tempdata);
data = tempdata;
}
catch (const std::out_of_range &e) {
std::cout << "\n " << e.what() << std::endl;
std::cout << "Please try again" << std::endl;
}
catch (const std::ios_base::failure &) {
std::cout << "\n Please enter numbers only!" << std::endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}
while (true);
std::cin.get();
return 0;
}
I can't see why this fails. Why does it loop forever after throwing the error?
bool undone;
do
{
undone = false;
try
{
o.spr(); // function throwing error E object
}
catch(E &r)
{
undone = true;
cout << r.reason << endl;
}
}
while(undone);
Here is the function:
void spr()
{
E r;
int n;
cout << " put n : "<<endl;
cin >> n;
if (cin.fail())
{
r.reason="fail !!";
throw r;
}
cout << " your n is : "<< n;
}
Your problem is recovering after the error.
First you have to clear the error flag from cin using cin.clear(). Then you have to read the bad input so it doesn't cause an error next time:
void spr()
{
E r;
int n;
cout << " put n : "<<endl;
cin >> n;
if (cin.fail())
{
cin.clear(); // clear the error flag
std::string bad_input;
cin >> bad_input; // skip over bad input
// now it is safe to re-use cin
r.reason="fail !!";
throw r;
}
cout << " your n is : "<< n;
}
Probably a better way to skip the bad input:
void spr()
{
E r;
int n;
cout << " put n : "<<endl;
cin >> n;
if (cin.fail())
{
cin.clear(); // clear the error flag
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // skip over bad input
r.reason="fail !!";
throw r;
}
cout << " your n is : "<< n;
}
The cin.ignore() function skips over the maximum possible number of input characters until it gets to an end of line '\n' character.
In case o.spr() throws, you set undone to true. Then condition in while() is checked, and it's true, so it loops, tries to call o.spr() again, and so on... Reconsider your undone flag and its value.
How would I check if the input is really a double?
double x;
while (1) {
cout << '>';
if (cin >> x) {
// valid number
break;
} else {
// not a valid number
cout << "Invalid Input! Please input a numerical value." << endl;
}
}
//do other stuff...
The above code infinitely outputs the Invalid Input! statement, so its not prompting for another input. I want to prompt for the input, check if it is legitimate... if its a double, go on... if it is NOT a double, prompt again.
Any ideas?
Try this:
while (1) {
if (cin >> x) {
// valid number
break;
} else {
// not a valid number
cout << "Invalid Input! Please input a numerical value." << endl;
cin.clear();
while (cin.get() != '\n') ; // empty loop
}
}
This basically clears the error state, then reads and discards everything that was entered on the previous line.
failbit will be set after using an extraction operator if there was a parse error, there are a couple simple test functions good and fail you can check. They are exactly the opposite of each other because they handle eofbit differently, but that's not an issue in this example.
Then, you have to clear failbit before trying again.
As casablanca says, you also have to discard the non-numeric data still left in the input buffer.
So:
double x;
while (1) {
cout << '>';
cin >> x;
if (cin.good())
// valid number
break;
} else {
// not a valid number
cout << "Invalid Input! Please input a numerical value." << endl;
cin.clear();
cin.ignore(100000, '\n');
}
}
//do other stuff...
I would use:
double x;
while (!(std::cin >> x)) {
std::cin.clear();
std::cin.ignore(2147483647, '\n');
std::cout << "Error.\n";
}
or
double x;
while ((std::cout << "> ") && !(std::cin >> x)) {
std::cin.clear();
std::cin.ignore(2147483647, '\n');
std::cout << "Error.\n";
}
#include <iostream>
#include <string>
bool askForDouble(char const *question, double &ret)
{
using namespace std;
while(true)
{
cout << question << flush;
cin >> ret;
if(cin.good())
{
return true;
}
if(cin.eof())
{
return false;
}
// (cin.fail() || cin.bad()) is true here
cin.clear(); // clear state flags
string dummy;
cin >> dummy; // discard a word
}
}
int main()
{
double x;
if(askForDouble("Give me a floating point number! ",x))
{
std::cout << "The double of it is: " << (x*2) << std::endl;
} else
{
std::cerr << "END OF INPUT" << std::endl;
}
return 0;
}
bool is_double(double val)
{
bool answer;
double chk;
int double_equl = 0;
double strdouble = 0.0;
strdouble = val;
double_equl = (int)val;
chk = double_equl / strdouble;
if (chk == 1.00)
{
answer = false; // val is integer
return answer;
} else {
answer = true; // val is double
return answer;
}
}
One way is to check for floating number equality.
double x;
while (1) {
cout << '>';
cin >> x;
if (x != int(x)) {
// valid number
break;
} else {
// not a valid number
cout << "Invalid Input! Please input a numerical value." << endl;
}
}
try
{
int selection;
if(selection > 4 || selection < 1)
throw selection;
}
catch(int selection)
{
cout << "Menu selection out of range." << endl;
}
The above code works fine for int values that are out of range, but I cannot get it to work if a char value is entered at (cin >> selection).
I have tried to post a catch block with an ellipsis [catch(...)] to account for char entries but that does not work.
I have also tried a catch block with [catch(char selection)] but that does not work either.
I would like to use an exception to handle this error as it would help in my overall project in other menu type areas.
You should try something with that snippet :
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
while (true) {
cout << "Please enter a valid number: ";
getline(cin, input);
// This code converts from string to number safely.
stringstream myStream(input);
if (myStream >> myNumber)
break;
cout << "Invalid number, please try again" << endl;
}
You can make cin capture input using a string, and throw an exception if you can't parse it as an int. One way of doing it would be to use the str2int function from Dan Moulding's answer in the following manner:
std::string str;
cin >> str;
int selection;
STR2INT_ERROR err = str2int(selection, str.c_str());
try
{
if(err != SUCCESS || selection > 4 || selection < 1)
throw str;
}
catch(std::string &selection)
{
cout << "Menu selection [" << selection << "] invalid" << endl;
}
{
int a;
try
{
cout << "Enter:";
cin >> a;
if (!a)
{
throw 1;
}
cout<<"Int";
}
catch (...)
{
cout << " no. Should be int" << '\n';
}
}
be careful
this code only work if input is char not if input is float