How does cin.clear() clear the input buffer? - c++

From what I have read, cin.clear() resets the flags, but how does this clear the input buffer?

cin.clear() has no effect on the input buffer. As you correctly read, it resets the iostate flags (technically, replaces their current value with std::ios_base::goodbit)

std::ios::clear() only resets the error flags, if possible. If there is, e.g., no stream buffer (i.e., stream.rdbuf() yield nullptr) the std::ios_base::badbit still stays set. That is the only affect. In particular, std::ios_base::clear() does not remove any characters from an input buffer.
If you need to remove character from the input buffer, you'll need to do it explicitly. For example you can use
stream.ignore(); to unconditionally remove the next character (if any; if there is none, the stream will get std::ios_base::eofbit set).
stream.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); to remove all character up to and including the first '\n' character encountered.
you might want to ignore() characters while stream.peek() yields a character class you don't like (e.g., while isdigit(stream.peek()) yields false)

cin.clear() doesn't clear the buffer, it only overwrites the current values of the flag.
For more details you can visit this link-->
http://www.cplusplus.com/reference/ios/ios/clear/
And You can find a good example in this link-->http://web.eecs.utk.edu/~plank/plank/classes/cs102/Cin-Notes/

Indeed cin.clear() has no effect on the input buffer it only sets a new value for the stream's internal error state flags.
If you want to clear the characters that "broke" your stream, you must use cin.ignore() (e.g., cin.ignore(10000,'\n');)
You can find a nice explanation with intuitive examples here: http://www.arachnoid.com/cpptutor/student1.html

Related

Is there a character that can be used as a delimiter for EOF?

I wrote a function that spellchecks a line read from a file which takes in a file stream and a delimiter as parameters. My problem is that the function requires a delimiter, but when reading in the last line, I haven't got one. I would use the last character of the file, but I need that last character for spellcheck purposes.
Is there any way to use the EOF macro as a delimiter?
Typically, you would let the stream tell you when it has received an EOF signal in whatever platform-dependent way is appropriate (be that the end of a file, or Ctrl+D on a Linux terminal emulator).
So, stop reading when you hit your custom delimiter, or when an attempt to read from the stream sets the stream's EOF bit. You ought to be checking the stream's state anyway — what if there's an error? You'll be looping forever at the moment.
That's how std::getline and co do it, anyway.

Can't read in a long cin input to a string

I have code that looks like this
string inputString;
std::getline (std::cin, inputString)
cout << inputString;
when I cin a long string ~30k characters then inputString only has part of that string. Any ideas how to fix this?
From the std::getline() documentation on cppreference.com:
getline reads characters from an input stream and places them into a string:
1. Behaves as UnformattedInputFunction, except that input.gcount() is not affected. After constructing and checking the sentry object, performs the following:
Calls str.erase()
Extracts characters from input and appends them to str until one of the following occurs (checked in the order listed)
a. end-of-file condition on input, in which case, getline sets eofbit.
b. the next available input character is delim, as tested by Traits::eq(c, delim), in which case the delimiter character is extracted from input, but is not appended to str.
c. str.max_size() characters have been stored, in which case getline sets failbit and returns.
If no characters were extracted for whatever reason (not even the discarded delimiter), getline sets failbit and returns.
2. Same as getline(input, str, input.widen('\n')), that is, the default delimiter is the endline character.
So check to see if your input is being limited by the value of inputString.max_size(). It might be near 32k on your system.
By default, the terminal works in canonical mode, and it has a buffer of the length 4096 Bytes. So that's why the maximum input that the string can take is 4095. Now the solution is to change to the noncanonical mode in Linux. You can do so by
$ stty -icanon # for switching to the noncanonical mode.
$ stty icanon # reverting back to the canonical mode when you are done.

input from a file using get line

I am trying to read from a file, and I have separated them by a new line character. I am using these code :
fstream input("wordfile.dat", ios::in);
char b[10];
while (!input.eof())
{
input.getline(b, 10);
cout << b << endl;
}
If I change the loop statement from while(!input.eof()) to while(input) , the program will output a blank line before the loop ends. But now it won't. The question is, in both statements the while condition must first input a line and by inputting it, it will know if it has reached end of file or if there is still more information. So input.eof() must act just like the other statement and output a blank line. First I thought it was a mistake, but I wondered why it was acting correctly. What is the difference between these two conditions?
Looking at operator bool we see ...
Notice that this function does not return the same as member good [...]
... that if (stream) is not the same as if (stream.good()), but also learn that it ...
Returns whether an error flag is set (either failbit or badbit).
So it's basically the same as not stream.fail() (which is true if either failbit or badbit is set).
This also explains the different behavior between while (stream) and while (not stream.eof()):
When the input file does not end with a newline, then stream.getline(buffer, size) will encounter the end of file before reaching the delimiting newline character (or the 10 character limit) and thus set the eofbit. Testing the stream with its operator bool will then be still true (since neither failbit nor badbit are set), and only after trying to read more using getline will set the failbit since no characters are extracted.
But when testing with not stream.eof(), the eofbit alone will end the loop.
If the stream is good, which is what you're testing with,
if (stream) // ...
then, this means that the stream is neither at the end of file (eof), nor bad nor failed.
So when it's not at the end of file, then it could still have failed or be in a bad state.
See the table here.
When reading (or writing) a stream, test for good unless you have a specific reason not to do so.
As a side note, this happens when you do input like the following, since getline returns a reference to the instance it's called on:
while (stream.getline(buffer, size)) {
// ..
}

Use of eof() in files in C++

Can anybody explain how this while condition works while accessing files in C++. In the while condition, employeeLine is a string.
while ( !inFile.getline( employeeLine, MAX_LINE, ‘\n’ ).eof( ) )
{
//some code here
}
If the file contains data like this then
will the code process the last line data or not as there is no newline character
Tomb33bb9.75<\n>
bbMarybb26bb10.15
(eof)
First of, inFile.getline(...) return the stream, i.e., a reference to inFile. When the stream reaches the end of file, the flag std::ios_base::eofbit gets set and inFile.eof() returns true. While there is any input, this flag won't be set. If the last line is incomplete, i.e., is lacking a newline character, it won't be processed!
Note, however, that the end of file may not necessarily be reached: if something goes wrong, std::ios_base::failbit is set and the stream won't response to any further attempts to read something: you'd have an infinite loop. std::istream::getline() does set std::ios_base::failbit when the line is too long to fit into the buffer (i.e., there are more than MAX_LINE - 1 characters). Another potential situation where the stream may go into failure mode without setting std::ios_base::eofbit is when an exception is thrown from the used stream buffer.
In general a better approach is to rely on the conversion to bool for a stream, i.e., to use
while (inFile.getline(employeeLine, MAX_LINE)) {
// ...
}
There is no need to pass '\n' as last parameter as it is the default. There is also no harm.
Note, that the above code won't deal with lines longer than MAX_LINE. That may be intentional, e.g., to avoid a denial of service attack based on infinitely large lines. Typically, it is preferable to use std::string, however:
for (std::string line; std::getline(inFile, line); ) {
// ...
}
If "inFile.getline( employeeLine, MAX_LINE, ‘\n’ ).eof( )" returns TRUE, it means that we reach the end of "inFile". So "!inFile.getline( employeeLine, MAX_LINE, ‘\n’ ).eof( )" means that we do not reach the end of "inFile".
See details in MSDN

Clearing keyboard buffer in C++

I one part of my application I have used Sleep(5000) (I need to wait 5 sec)
The problem is that if the user presses any keyboard key during these 5 seconds, the keys will be read after sleep and it causes problems for my app.
How can I empty the buffer after sleep?
I tried cin.clear() and setbuf(stdin, NULL) but they can't clear the buffer if there is more than one character in the buffer.
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.
The simplest way to clear the keyboard input buffer is
while(kbhit()) getch();
just put that code in your program wherever you want to clear your buffer .
headerfile needed for that is conio.h
This seems to work for Windows 10 compiled with Code::Blocks:
#include <conio.h>
/**
* clears keyboard buffer
*
* #author Shaun B
* #version 0.0.2
* #fixed 15-01-2016
*/
void clearKeyboardBuffer()
{
while (_kbhit())
{
_getche();
}
}
Then called from where is needed in your C++ script.