The two functions you are using don't have the effect you expect them to have:
clear()
doesn't affect the buffer at all but rather clears the error flags. That is, if there was an unsuccessful read a flag is set (std::ios_base::failbit
). While any error flag is set (there are a few more), the stream won't attempt to read anything.
setbuf(0, 0)
affects the stream's internal buffer to not exist (calls with non-null values have implementation-defined meaning which is typically "do nothing"). This is generally a Bad Idea because it causes the streams to be very slow. Also, the keys pressed by a user are probably not stored in this buffer anyway but rather in the operating systems input buffer until they are sent to application (there are platform specific ways to turn off the operating system input buffer, e.g., on POSIX you'd use tcsetattr()
to set the input into non-canonical mode).
In either case, not having a buffer doesn't really help you anyway: The user may very well have typed valid input. The proper approach is to attempt reading the available input and, if this fails, to rid of the offending character (or characters). To this end you'd attempt to read the input and if it fails you'd clear()
the stream and ignore()
one or more characters (this example ignores an entire line; call ignore()
without parameters to just ignore one character):
T value;
while (!(std::cin >> value)) {
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
You always need to verify that the input was successful anyway and the few extra lines are just adding a bit of recovery code.