Stephen
Stephen

Reputation: 1

cin.ignore() can not remove input buffer

I have a problem that cin.ignore() can not remove input from the buffer.

#include <iostream>
#include <string>

int main() {
    using namespace std;

    int x=0;
    string k;
    cin >> x;
    cin.ignore(100,'\n');
    cin.clear();
    cin >> k;
    cout << k << endl;
}

For the above code:

input : abc (program ends when I just input abc)
output : abc

I was really surprised because cin.ignore() did not remove "abc" from the input buffer.

What is wrong with my code?

If I change the positions of cin.ignore() and cin.clear(), it works well, why is that?

Upvotes: 0

Views: 158

Answers (2)

NiluscheL.
NiluscheL.

Reputation: 1

cin.clear(); removes the error flag from cin and cin.ignore(); ignores the next numbers of spaces. Since you declared x as a Integer and you write it in first, the console expects that an integer to be read first. if you type abc at first instead you are typing in a string and the console returns an error flag because it expects an integer. That's why your program ends right after that. If you put cin.clear(); right after cin>>x and type abc the error flag that is been thrown will be ignored and the console continues with cin>>k

Upvotes: 0

Remy Lebeau
Remy Lebeau

Reputation: 595792

This code:

int x=0;
cin >> x;

Causes cin to be put into an error state (specifically, the failbit flag is set) if the input is not convertible to an int.

Per cppreference.com:

std::basic_istream<CharT,Traits>::operator>>:

This function behaves as a FormattedInputFunction. After constructing and checking the sentry object, which may skip leading whitespace, extracts an integer value by calling std::num_get::get().

...

If extraction fails (e.g. if a letter was entered where a digit is expected), value is left unmodified and failbit is set. (until C++11)

If extraction fails, zero is written to value and failbit is set. For signed integers, if extraction results in the value too large or too small to fit in value, std::numeric_limits<T>::max() or std::numeric_limits<T>::min() (respectively) is written and failbit flag is set. For unsigned integers, if extraction results in the value too large or too small to fit in value, std::numeric_limits<T>::max() is written and failbit flag is set. (since C++11)

...

Thus, any further I/O operations on the stream are disabled, like ignore(), until you clear() the error state to re-enable I/O.

std::basic_ios<CharT,Traits>::clear:

Sets the stream error state flags by assigning them the value of state. By default, assigns std::ios_base::goodbit which has the effect of clearing all error state flags.

std::basic_istream<CharT,Traits>::ignore:

ignore behaves as an UnformattedInputFunction. After constructing and checking the sentry object, it extracts characters from the stream and discards them until any of the following conditions occurs:

...

C++ named requirements: UnformattedInputFunction:

An UnformattedInputFunction is a stream input function that performs the following:

  • Constructs an object of type basic_istream::sentry with automatic storage duration and with the noskipws argument set to true, which performs the following

    • if eofbit or badbit are set on the input stream, sets the failbit as well, and if exceptions on failbit are enabled in this input stream's exception mask, throws ios_base::failure.

    • flushes the tie()'d output stream, if applicable

  • Checks the status of the sentry by calling sentry::operator bool(), which is equivalent to basic_ios::good.

  • If the sentry returned false or sentry's constructor threw an exception:

    • sets the number of extracted characters (gcount) in the input stream to zero

    • if the function was called to write to an array of CharT, writes CharT() (the null character) to the first location of the array

...

Upvotes: 2

Related Questions