Reputation: 999
I know how to do this in C but have no idea for a C++ solution. I want the following to be fail safe, but after providing a string or even a char to the input, the program hangs. How to read input stream including \n to free it?
int main() {
int num;
do {
std::cin.clear();
std::cin >> num;
while ( std::cin.get() != '\n' );
} while ( !std::cin.good() || num > 5 );
return 0;
}
Upvotes: 3
Views: 6341
Reputation: 11
To clear input stream, use cin.sync() . no need to use cin.clear() or cin.ignore().
Upvotes: 0
Reputation: 1
One way would be to check the state after every input and throw an exception if that happens for example:
#include<iostream>
using namespace std;
int main(){
int a;
cout<<"Enter a number: ";
cin>>a;
//If a non number is entered, the stream goes into a fail state
try
{
if(cin.fail()){
throw 0;
cin.clear();
cin.ignore();
}
}
catch(int){
cin.clear();
cin.ignore();
}
return 0;
}
After that you can continue with whatever code you wish
Upvotes: 0
Reputation: 11
I would approach it using getline(cin,num) and then catch any fails using cin.fail(). I usually use cin.fail() with ints but theoretically should work with strings and chars also, for example :
string num;
getline(cin,num);
if(cin.fail())
{
cin.clear();
cin.ignore();
}
Upvotes: 0
Reputation: 19815
To build on top of R. Martinho Fernandes answer, here is a possible C++ alternative to your code:
std::string num;
std::getline(std::cin, num);
// Arbitrary logic, e.g.: remove non digit characters from num
num.erase(std::remove_if(num.begin(), num.end(),
std::not1(std::ptr_fun((int(*)(int))std::isdigit))), num.end());
std::stringstream ss(num);
ss >> n;
std::getline
function extracts characters from cin
and stores to num
. It also extracts and discards the delimiter at the end of the input (you can specify your own delimiter or \n
will be used).string::erase
function removes all characters but digits from the num
string, using std::remove_if
with a negative std::isdigit
predicate.std::stringstream
(a boost::lexical_cast
would have worked as well)The logic here implemented by the erase function can be any other logic, but this code is probably much simpler to read than the one included in the question.
Upvotes: 1
Reputation: 234514
Once the stream is in an error state all read operations will fail. This means that, if the cin >> num
read fails, the loop with the get()
calls will never end: all those get()
s will fail. Skipping to the end of the line can only be done after clearing the error state.
Upvotes: 2