Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return value of istream::get()

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 available

Returns: c if available, otherwise traits::eof()

This text suggests that negative chars 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?

like image 737
M.M Avatar asked Jun 30 '14 03:06

M.M


People also ask

Is get () C++?

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.

What is the return type of Getline in C++?

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.

How does istream work c++?

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 ).

How do I read an istream?

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() .


1 Answers

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;
like image 103
Ulrich Eckhardt Avatar answered Sep 28 '22 06:09

Ulrich Eckhardt