This question is about the member function of basic_istream
:
int_type get();
as described by N3337 27.7.2.3#4 (that is [istream.unformatted]). Presumably the actual Standard text is the same.
The text says:
After constructing a sentry object, extracts a character
c
, if one is availableReturns:
c
if available, otherwisetraits::eof()
This text suggests that negative char
s should return a negative value. We could compare with the next section, basic_istream<charT,traits>& get(char_type &c)
, which says:
After constructing a sentry object, extracts a character, if one is available, and assigns it to
c
.
This is very similar wording to get()
.
However, when I try get()
, negative chars return a positive value; i.e. basic_istream::get()
behaves like the C function getchar()
. This would be the sensible behaviour (to allow signalling of EOF), however the Standard text does not seem to specify this. The C99 description of getchar()
and friends specifically says that it returns the value converted to an unsigned char. But basic_istream::get()
does not have any equivalant text.
My question is: is get()
meant to be specified to return a value in the range 0...UCHAR_MAX
union EOF
? Or should it return the actual char
converted to int_type
(via implicit conversion)? Or something else? What exactly does and does not the Standard specify here?
If "something else", how do I transform the result of int i = cin.get()
to match the char value read by char ch; cin.get(ch);
for the same input character?
What is gets() in C++ The gets() function in C++ reads characters from the stdin until a new line or end of the file is reached. It accepts a pointer to the memory where it stores those array of characters.
Returned value If successful, getline() returns the number of characters that are read, including the newline character, but not including the terminating null byte ( '\0' ). This value can be used to handle embedded null bytes in the line read.
std::istream::operator>> Extracts and parses characters sequentially from the stream to interpret them as the representation of a value of the proper type, which is stored as the value of val . Internally, the function accesses the input sequence by first constructing a sentry object (with noskipws set to false ).
Other ways to read a std::istreamTo read a line of input, try the getline() function. For this, you need #include <string> in addition to #include <iostream> . To read a single char: use the get() method. To read a large block of characters, either use get() with a char[] as the argument, or use read() .
To clear up your confusion, the difference just doesn't matter. Think about what you can or can't do with the returnvalue of parameterless get()
. The funny thing is that you can't reliably compare it to EOF
or traits_type::eof()
, because it's not ever guaranteed to be equality-comparable (it is for builtin char
and wchar_t
though). In order to compare it correctly, you just use traits_type::eq_int_type()
. Similarly, in order to extract a character from it after checking for EOF, you use traits_type::to_char_type()
, and that function then converts the type accordingly. Similarly, get()
can't use the implicit conversion but has to use traits_type::to_int_type()
.
In summary, the guarantee for getchar()
that it returns the "unsigned" value or EOF is not necessary, since the traits_type
encapsulates this knowledge and should be used for correct code.
Example use of parameterless istream::get():
traits_type::int_type c = in.get();
if(traits_type::not_eof(c))
my_string += traits_type::to_char_type(c);
Similar use of single-parameter istream::get():
traits_type::char_type c;
in.get(c);
if(in) // check for EOF or other input failure
my_string += c;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With