Reputation: 6390
The buffer z[]
gets the null character in its first byte when the EOF (Ctrl+Z in Windows) is entered to finish the loop. Why is this?
#include <iostream>
using namespace std;
int main()
{
char z[10];
while( cin >> z ) cout << z << '\n';
if( cin.eof() ) cout << z << "End of input\n";
}
This doesn't happen below, i.e., z
will keep the last character read from the keyboard.
#include <iostream>
using namespace std;
int main()
{
char z;
while( cin >> z ) cout << z << '\n';
if( cin.eof() ) cout << z << "End of input\n";
}
Upvotes: 1
Views: 320
Reputation: 385194
Because the standard says so!
You're giving the stream what looks like a C-string buffer. Even if the extraction results in a failure bit being set, it wants to terminate what it put in that buffer (in this case, the empty string).
Here's the proof, from the definition of template<class charT, class traits>
basic_istream<charT,traits>& operator>>(basic_istream<charT,traits>& in,
charT* s)
:
[C++11: 27.7.2.2.3/8]
: Characters are extracted and stored until any of the following occurs:
n-1
characters are stored;- end of file occurs on the input sequence;
ct.is(ct.space,c)
is true for the next available input characterc
, wherect
isuse_facet<ctype<charT> >(in.getloc())
.
[C++11: 27.7.2.2.3/9]:
operator>>
then stores a null byte (charT()
) in the next position, which may be the first position if no characters were extracted.
It bears mentioning that this is the case for extraction into a std::string
, too:
[C++11: 21.4.8.9/1]:
Effects: Behaves as a formatted input function (27.7.2.2.1). After constructing a sentry object, if the sentry converts to true, callsstr.erase()
and then extracts characters fromis
and appends them tostr
as if by callingstr.append(1,c)
. Ifis.width()
is greater than zero, the maximum number n of characters appended isis.width()
; otherwise n isstr.max_size()
. 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())
istrue
for the next available input characterc
That is, for both a char
buffer and a std::string
, if the stream is in a valid state immediately before the extraction, even if the extraction pulls out zero characters before reaching EOF, your input object will be "cleared".
No such rule exists for a single char
:
[C++11: 27.7.2.2.3/12]:
Effects: Behaves like a formatted input member (as described in 27.7.2.2.1) ofin
. After a sentry object is constructed a character is extracted fromin
, if one is available, and stored inc
. Otherwise, the function callsin.setstate(failbit)
.
The original value is left unperturbed if there weren't a new one to take its place.
Upvotes: 5