Here is the code
double enter_number()
{
double number;
while(1)
{
cin>>number;
if(cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input " << endl;
}
else
break;
cout<<"Try again"<<endl;
}
return number;
}
My problem is that when I enter something like 1x, then 1 is taken as input without noticing the character that is left out for another run.
Is there any way how to make it work with any real number e.g. 1.8?
When cin encounters an input it can't properly read in to the variable specified (such as inputing a character into an integer variable), it goes into an error state and leaves the input in it's buffer.
You have to do several things to properly handle this scenario.
You have to test for this error state.
You have to clear the error state.
You have to either alternatively handle the input data that generated the error state, or flush it out and reprompt the user.
The following code provides one of numerous methods of doing these three things.
#include<iostream>
#include<limits>
using namespace std;
int main()
{
cout << "Enter an int: ";
int x = 0;
while(!(cin >> x)){
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input. Try again: ";
}
cout << "You enterd: " << x << endl;
}
You could just pass in some large value to cin.ignore like 1000 and it's likely to behave exactly the same for all practical purposes.
You can also test cin after the input attempt and handle it that way, something like
if(!cin){//clean up the error} .
Check out the istream reference for other member functions to handle stream state: http://cplusplus.com/reference/iostream/istream/
I would use std::getline and std::string to read the whole line and then only break out of the loop when you can convert the entire line to a double.
#include <string>
#include <sstream>
int main()
{
std::string line;
double d;
while (std::getline(std::cin, line))
{
std::stringstream ss(line);
if (ss >> d)
{
if (ss.eof())
{ // Success
break;
}
}
std::cout << "Error!" << std::endl;
}
std::cout << "Finally: " << d << std::endl;
}
Related
Here is the code
double enter_number()
{
double number;
while(1)
{
cin>>number;
if(cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input " << endl;
}
else
break;
cout<<"Try again"<<endl;
}
return number;
}
My problem is that when I enter something like 1x, then 1 is taken as input without noticing the character that is left out for another run.
Is there any way how to make it work with any real number e.g. 1.8?
When cin encounters an input it can't properly read in to the variable specified (such as inputing a character into an integer variable), it goes into an error state and leaves the input in it's buffer.
You have to do several things to properly handle this scenario.
You have to test for this error state.
You have to clear the error state.
You have to either alternatively handle the input data that generated the error state, or flush it out and reprompt the user.
The following code provides one of numerous methods of doing these three things.
#include<iostream>
#include<limits>
using namespace std;
int main()
{
cout << "Enter an int: ";
int x = 0;
while(!(cin >> x)){
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input. Try again: ";
}
cout << "You enterd: " << x << endl;
}
You could just pass in some large value to cin.ignore like 1000 and it's likely to behave exactly the same for all practical purposes.
You can also test cin after the input attempt and handle it that way, something like
if(!cin){//clean up the error} .
Check out the istream reference for other member functions to handle stream state: http://cplusplus.com/reference/iostream/istream/
I would use std::getline and std::string to read the whole line and then only break out of the loop when you can convert the entire line to a double.
#include <string>
#include <sstream>
int main()
{
std::string line;
double d;
while (std::getline(std::cin, line))
{
std::stringstream ss(line);
if (ss >> d)
{
if (ss.eof())
{ // Success
break;
}
}
std::cout << "Error!" << std::endl;
}
std::cout << "Finally: " << d << std::endl;
}
Here is the code
double enter_number()
{
double number;
while(1)
{
cin>>number;
if(cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input " << endl;
}
else
break;
cout<<"Try again"<<endl;
}
return number;
}
My problem is that when I enter something like 1x, then 1 is taken as input without noticing the character that is left out for another run.
Is there any way how to make it work with any real number e.g. 1.8?
When cin encounters an input it can't properly read in to the variable specified (such as inputing a character into an integer variable), it goes into an error state and leaves the input in it's buffer.
You have to do several things to properly handle this scenario.
You have to test for this error state.
You have to clear the error state.
You have to either alternatively handle the input data that generated the error state, or flush it out and reprompt the user.
The following code provides one of numerous methods of doing these three things.
#include<iostream>
#include<limits>
using namespace std;
int main()
{
cout << "Enter an int: ";
int x = 0;
while(!(cin >> x)){
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input. Try again: ";
}
cout << "You enterd: " << x << endl;
}
You could just pass in some large value to cin.ignore like 1000 and it's likely to behave exactly the same for all practical purposes.
You can also test cin after the input attempt and handle it that way, something like
if(!cin){//clean up the error} .
Check out the istream reference for other member functions to handle stream state: http://cplusplus.com/reference/iostream/istream/
I would use std::getline and std::string to read the whole line and then only break out of the loop when you can convert the entire line to a double.
#include <string>
#include <sstream>
int main()
{
std::string line;
double d;
while (std::getline(std::cin, line))
{
std::stringstream ss(line);
if (ss >> d)
{
if (ss.eof())
{ // Success
break;
}
}
std::cout << "Error!" << std::endl;
}
std::cout << "Finally: " << d << std::endl;
}
Here is the code
double enter_number()
{
double number;
while(1)
{
cin>>number;
if(cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input " << endl;
}
else
break;
cout<<"Try again"<<endl;
}
return number;
}
My problem is that when I enter something like 1x, then 1 is taken as input without noticing the character that is left out for another run.
Is there any way how to make it work with any real number e.g. 1.8?
When cin encounters an input it can't properly read in to the variable specified (such as inputing a character into an integer variable), it goes into an error state and leaves the input in it's buffer.
You have to do several things to properly handle this scenario.
You have to test for this error state.
You have to clear the error state.
You have to either alternatively handle the input data that generated the error state, or flush it out and reprompt the user.
The following code provides one of numerous methods of doing these three things.
#include<iostream>
#include<limits>
using namespace std;
int main()
{
cout << "Enter an int: ";
int x = 0;
while(!(cin >> x)){
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input. Try again: ";
}
cout << "You enterd: " << x << endl;
}
You could just pass in some large value to cin.ignore like 1000 and it's likely to behave exactly the same for all practical purposes.
You can also test cin after the input attempt and handle it that way, something like
if(!cin){//clean up the error} .
Check out the istream reference for other member functions to handle stream state: http://cplusplus.com/reference/iostream/istream/
I would use std::getline and std::string to read the whole line and then only break out of the loop when you can convert the entire line to a double.
#include <string>
#include <sstream>
int main()
{
std::string line;
double d;
while (std::getline(std::cin, line))
{
std::stringstream ss(line);
if (ss >> d)
{
if (ss.eof())
{ // Success
break;
}
}
std::cout << "Error!" << std::endl;
}
std::cout << "Finally: " << d << std::endl;
}
double checkInput() {
double add;
cout << "\n" << endl;
cin >> add;
if (cin.fail()==true)
{
cin.clear();
cin.ignore(INT_MAX, '\n');
cout << "Incorrect input"<<endl;
}
else
{
return add;
}
}
I use this bit of code to filter out character inputs eg "Blarg","bat12cat" and similar inputs where the character/letter come first but when i test with "1gold" ,"0.05cake" etc where number comes first then letters,the program accepts the all numbers up to the first instance of a letter.
My understanding is that it is the cin.ignore() that is causing the issue and is allowing the numbers through.
What would let inputs like"0.05Cats" be ignored/skipped altogether?.
Searching online,people suggest using getline() and stringstream.
Thank you.
When you input something like 1.5dog and then use cin >> some_double; >> is going to extract out a double until it can't read any more. So some_double gets the 1.5 and dog is still in the stream. This is not a failure and as such the failbit is not set. Since it is not set you skip your if statement and return the double value while the rest of the input stays in the stream and will cause you issues the next time you try to read from the stream. My suggestion is to change how you read your inputs. You can take in the input via a std::string and then convert it to the desired type. Then if the conversion fails you you can signal that you had a failure. I would use something like:
bool read_double(std::istream & is, double & number)
{
std::string line;
getline(is, line);
std::size_t pos = 0;
double temp = stod(line, &pos);
if (pos != line.size()) // there is extra content in the streams
return false;
number = temp;
return true;
}
And you can see it working with this Live Example
Usually there is more than one way to do the right thing. Using "c++(11) regex class object" would help you. You can edit regex for your needs (for example to include hex numbers by adding -a,b,c,d,e,f).
#include <iostream>
using namespace std;
#include <string>
using std::string;
#include <regex>
void main()
{
string input;
std::regex reg("[-+]?([0-9]*\.[0-9]+|[0-9]+)");
cout << "Please enter a double type\n";
while (cin >> input)
{
if (std::regex_match(input, reg))
{
std::cout << "Valid input\n";
break;
}
else
{
cout << "Invalid input\n";
cout << "Please enter a double type\n";
}
}
double do_with = std::stod(input,NULL);
cout << "the double is : " << do_with << endl;
cin >> input; // to hold the shell
}
Here is the code
double enter_number()
{
double number;
while(1)
{
cin>>number;
if(cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input " << endl;
}
else
break;
cout<<"Try again"<<endl;
}
return number;
}
My problem is that when I enter something like 1x, then 1 is taken as input without noticing the character that is left out for another run.
Is there any way how to make it work with any real number e.g. 1.8?
When cin encounters an input it can't properly read in to the variable specified (such as inputing a character into an integer variable), it goes into an error state and leaves the input in it's buffer.
You have to do several things to properly handle this scenario.
You have to test for this error state.
You have to clear the error state.
You have to either alternatively handle the input data that generated the error state, or flush it out and reprompt the user.
The following code provides one of numerous methods of doing these three things.
#include<iostream>
#include<limits>
using namespace std;
int main()
{
cout << "Enter an int: ";
int x = 0;
while(!(cin >> x)){
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input. Try again: ";
}
cout << "You enterd: " << x << endl;
}
You could just pass in some large value to cin.ignore like 1000 and it's likely to behave exactly the same for all practical purposes.
You can also test cin after the input attempt and handle it that way, something like
if(!cin){//clean up the error} .
Check out the istream reference for other member functions to handle stream state: http://cplusplus.com/reference/iostream/istream/
I would use std::getline and std::string to read the whole line and then only break out of the loop when you can convert the entire line to a double.
#include <string>
#include <sstream>
int main()
{
std::string line;
double d;
while (std::getline(std::cin, line))
{
std::stringstream ss(line);
if (ss >> d)
{
if (ss.eof())
{ // Success
break;
}
}
std::cout << "Error!" << std::endl;
}
std::cout << "Finally: " << d << std::endl;
}