Good day, my teacher said that I should learn what makes function cin.clear() in C ++. I was looking for, but a normal explanation was never found. This resource is cplusplus said that this function
Sets a new value for the stream's internal error state flags. The current value of the flags is overwritten: All bits are replaced by those in state; If state is goodbit (which is zero) all error flags are cleared.
But I do not quite understand what the "state"and from there there are flags and error, which is why, and how well we replace them at 0 value. And what is the "flags" and why they are needed. And as he said that I should know what parameters or data which takes a function cin.clear() and returns, I understand that it does not returns, but it also takes something? Please help. Sorry for bad English, I write through a translator.
The function std::basic_ios<>::clear() affects the
std::ios_base::iostate bits, which are, for the most part,
error conditions. The standard defines "four" bits:
badbit
Set if the last input failed because of some hardware failure,
e.g. a read error on the disk. (In practice, I'm not sure that
all implementations check for this; I suspect that some will
just treat this as if there were an end of file.)
failbit
Set if the last input failed for some reason other than that
which would of set the badbit. The most common
reasons are a format error (trying to read an `int` when the
next characters in input were `"abc"`) and encountering end of
file _before_ having been able to read sufficient data for the
requested input.
eofbit
This is _not_ an error condition; it will be set anytime the
stream sees the end of file. This may be because it needs yet
another character in order to parse the input, in which case the
failbit will also be set; but it may also be
because the input stream saw the end of file on look-ahead.
(For this last case, consider inputting an int, where the
remaining characters in the stream are "123", with no trailing
whitespace, not even a new line. In order to know that it has
processed all of the relevant characters, the stream must try to
read a character after the 3. In which case, it sets
eofbit, to remember that it has seen the end of
file, but it does _not_ set failbit, because "123"
is a valid complet input for an int.)
goodbit
This isn't even a bit pattern, but simply a special value in
which none of the preceding bits are set.
For the most part, failbit and eofbit are only relevant on
input; you'll get (or should get) badbit on output if the disk
is full.
Related
I know that we can use std::cin as a condition, for example, in
while (std::cin >> value)
using std::cin as a condition will call a member function std::ios::operator bool. It says that
it "returns whether an error flag is set (either failbit or badbit)", which does not include
eofbit. Despite this, passing end-of-file (by Ctrl+d) terminates the loop. Why? Can failbit or badbit also set an eofbit?
I also found this explanation, but in C++ Reference it specifically says that "this function does not return the same as member good"
The loop above does not test for end of file. It tests for failure to read a value, end of file is just one possible cause of this. Even end of file does not necessarily cause a failure to read a value, imagine reading an integer where the digits are terminated by the end of file, you still read an integer even though you hit the end of file.
The bottom line is that failure to read a value for any reason sets the fail bit, and this loop tests for that.
I could not find pretty much any information on this. Whether and if so, under what circumstances, can eofbit be set (meaning ofstream_instance.eof() is true )?
I am more interested in an independent ofstream, one that is not associated with an ifstream within some fstream, so that the "shared" eofbit can't be set by the ifstream (if something like that is possible).
If I simply write to a file and there is no space on disk or operation system does not provide another space for the writing, then I'd expect just only either failbit or badbit to be set, but reaching end of file while writing to it does not make sense to me. However no discussion on this I was able to find.
No. eof() returns the eofbit, which has no real meaning for an output stream with no associated input stream.
eofbit indicates that an input operation reached the end of an input sequence
[ios.types] / 3.1, Table 107
The actions that set eofbit are enumerated here, and they all act on input streams only.
We could imagine some weird implementation-specific scenario in which EOF (as opposed to some other error condition) would be hit while writing to a file - maybe there is a fixed-size file buffer we are writing to through some OS functions - but as far as I know the standard library abstractions do not deal with that case, and I have never seen or heard of such an API in the first place.
It seems well accepted that the istream::peek operation is blocking.
The standard, though arguably a bit ambiguous, leans towards nonblocking behavior. peek calls sgetc in turn, whose behavior is:
"The character at the current position of the controlled input sequence, as a value of type int.
If there are no more characters to read from the controlled input sequence, the function returns the end-of-file value (EOF)."
It doesn't say "If there are no more characters.......wait until there are"
Am I missing something here? Or are the peek implementations we use just kinda wrong?
The controlled input sequence is the file (or whatever) from which you're reading. So if you're at end of file, it returns EOF. Otherwise it returns the next character from the file.
I see nothing here that's ambiguous at all--if it needs a character that hasn't been read from the file, then it needs to read it (and wait till it's read, and return it).
If you're reading from something like a socket, then it's going to wait until data arrives (or the network stack detects EOF, such as the peer disconnecting).
The description from cppreference.com might be clearer than the one in your question:
Ensures that at least one character is available in the input area by [...] reading more data in from the input sequence (if applicable)."
"if applicable" does apply in this case; and "reading data from the input sequence" entails waiting for more data if there is none and the stream is not in an EOF or other error state.
When I get confused about console input I remind myself that console input can be redirected to come from a file, so the behavior of the keyboard more or less mimics the behavior of a file. When you try to read a character from file, you can get one of two results: you get a character, or you get EOF because you've reached the end of the file -- there are no more characters to be read. Same thing for keyboard input: either you get a character, or you get EOF because you've reached the end of the file. With a file, there is no notion of waiting for more characters: either a file has unread characters or it doesn't. Same thing for the keyboard. So if you have't reached EOF on the keyboard, reading a character returns the next character. You reach EOF on the keyboard by typing whatever character your system recognizes as EOF; on Unix systems that's ctrl-D, on Windows (if I remember correctly) that's ctrl-C. If you haven't reached EOF, there are more characters to be read.
What are the possible errors in std::stringstream?
Specifically, std::stringstream derives off of std::ios, which means that it has an std::ios::rdstate. In std::ios::rdstate, we have a problem when either failbit or badbit are set. As such, what are the possible ways to set the failbit and badbit in std::stringstream?
Are the ways to set failbit and badbit compiler/implementation dependent or are they specified by the standard?
Table 124 in C++11 specifies what the individual bits mean:
badbit indicates a loss of integrity in an input or output sequence (such as an
irrecoverable read error from a file);
eofbit indicates that an input operation reached the end of an input sequence;
failbit indicates that an input operation failed to read the expected characters, or
that an output operation failed to generate the desired characters.
As to what operations set those bits, that's scattered around the standard in various places, you can just search for occurrences of the mask to find out what sets and clears it.
For example, one way the badbit can be set is if you use the get an exception during an operator>> call to an istream. This is detailed in 27.7.2.2 Formatted input functions. There are many other places throughout the standard which give similar descriptions.
Let's say we have a stream containing simply:
hello
Note that there's no extra \n at the end like there often is in a text file. Now, the following simple code shows that the eof bit is set on the stream after extracting a single std::string.
int main(int argc, const char* argv[])
{
std::stringstream ss("hello");
std::string result;
ss >> result;
std::cout << ss.eof() << std::endl; // Outputs 1
return 0;
}
However, I can't see why this would happen according to the standard (I'm reading C++11 - ISO/IEC 14882:2011(E)). operator>>(basic_stream<...>&, basic_string<...>&) is defined as behaving like a formatted input function. This means it constructs a sentry object which proceeds to eat away whitespace characters. In this example, there are none, so the sentry construction completes with no problems. When converted to a bool, the sentry object gives true, so the extractor continues to get on with the actual extraction of the string.
The extraction is then defined as:
Characters are extracted and appended until any of the following occurs:
n characters are stored;
end-of-file occurs on the input sequence;
isspace(c,is.getloc()) is true for the next available input character c.
After the last character (if any) is extracted, is.width(0) is called and the sentry object k is destroyed.
If the function extracts no characters, it calls is.setstate(ios::failbit), which may throw ios_base::failure (27.5.5.4).
Nothing here actually causes the eof bit to be set. Yes, extraction stops if it hits the end-of-file, but it doesn't set the bit. In fact, the eof bit should only be set if we do another ss >> result;, because when the sentry attempts to gobble up whitespace, the following situation will occur:
If is.rdbuf()->sbumpc() or is.rdbuf()->sgetc() returns traits::eof(), the function calls setstate(failbit | eofbit)
However, this is definitely not happening yet because the failbit isn't being set.
The consequence of the eof bit being set is that the only reason the evil-idiom while (!stream.eof()) doesn't work when reading files is because of the extra \n at the end and not because the eof bit isn't yet set. My compiler is happily setting the eof bit when the extraction stops at the end of file.
So should this be happening? Or did the standard mean to say that setstate(eofbit) should occur?
To make it easier, the relevant sections of the standard are:
21.4.8.9 Inserters and extractors [string.io]
27.7.2.2 Formatted input functions [istream.formatted]
27.7.2.1.3 Class basic_istream::sentry [istream::sentry]
std::stringstream is a basic_istream and the operator>> of std::string "extracts" characters from it (as you found out).
27.7.2.1 Class template basic_istream
2 If rdbuf()->sbumpc() or rdbuf()->sgetc() returns traits::eof(), then the input function, except as
explicitly noted otherwise, completes its actions and does setstate(eofbit), which may throw ios_-
base::failure (27.5.5.4), before returning.
Also, "extracting" means calling these two functions.
3 Two groups of member function signatures share common properties: the formatted input functions (or
extractors) and the unformatted input functions. Both groups of input functions are described as if they
obtain (or extract) input characters by calling rdbuf()->sbumpc() or rdbuf()->sgetc(). They may use
other public members of istream.
So eof must be set.
Intuitively speaking, the EOF bit is set because during the read operation to extract the string, the stream did indeed hit the end of the file. Specifically, it continuously read characters out of the input stream, stopping because it hit the end of the stream before encountering a whitespace character. Accordingly, the stream set the EOF bit to mark that the end of stream was reached. Note that this is not the same as reporting failure - the operation was completed successfully - but the point of the EOF bit is not to report failure. It's to mark that the end of the stream was encountered.
I don't have a specific part of the spec to back this up, though I'll try to look for one when I get the chance.