infoholic_anonymous
infoholic_anonymous

Reputation: 999

How to empty the input stream in C++?

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

Answers (5)

kushal
kushal

Reputation: 11

To clear input stream, use cin.sync() . no need to use cin.clear() or cin.ignore().

Upvotes: 0

Asiedu Opare Kwame
Asiedu Opare Kwame

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

CodeCompileHack
CodeCompileHack

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

Vincenzo Pii
Vincenzo Pii

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;
  • The 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).
  • The string::erase function removes all characters but digits from the num string, using std::remove_if with a negative std::isdigit predicate.
  • The string is then represented as an integer using a 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

R. Martinho Fernandes
R. Martinho Fernandes

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

Related Questions