1

I am learning about implicit conversions in C++. And i read the following example:

char a;
std::cin>>a; //I can enter an integer like 56 here
std::cout<<a<<std::endl; //for the input 56 it will display 5 because of its ASCII value

I understood the above example by reading about it in different books and posts on SO. For example, if i provide the input J, then the program successfully prints J on the console. Similarly if i provide the input say 56 then the output will be 5 because of its ASCII value.


But then i tried the opposite as shown below:

int a;
std::cin>>a;//if i provide the input as the character J then why is the output 0 instead of the corresponding code point of `J`
std::cout<<a<<std::endl;

For the above snippet, if i provide the input 56 then the output is correctly printed as 56. But if i provide the input as J then the output is 0.

So my question is in the above 2nd snippet why the code point corresponding to the character J is not printed and instead we get 0 printed on the console. I mean, a is an integer variable so it is able to store the code point corresponding to the character J and then when we do cout<<a; we should be getting that code point as the output instead of 0. What is happening here. Is this related to implicit conversion like a char can be promoted to an int or something else.

Jason
  • 36,170
  • 5
  • 26
  • 60
  • 4
    Your comments in the first passage are incorrect. The output is `5` because `'5'` is the first character you entered and `'5'` got stored in `a`, not because the ASCII value of `'5'` is `56`. – Nathan Pierson Apr 18 '22 at 05:34
  • When you read characters, you will read actual characters. If you give the input `56` then the character `'5'` will be stored in the variable `a`, not the integer value `56` (which is the ASCII encoded value for the character `'8'`). – Some programmer dude Apr 18 '22 at 05:35
  • @Someprogrammerdude Ok, can you explain in an answer what exactly happens in the 2nd snippet. I get your point about the 1st snippet. – Jason Apr 18 '22 at 05:38
  • 3
    @273K Since C++11 it does initialize the variables to zero. See e.g. [this old answer of mine](https://stackoverflow.com/questions/13378989/why-does-stringstream-change-value-of-target-on-failure/13379073#13379073). – Some programmer dude Apr 18 '22 at 05:38
  • 1
    @Richard In the second example the extraction fails since you don't give an integer as input, which will set the variable to zero and set the `failbit` state in the stream. – Some programmer dude Apr 18 '22 at 05:40
  • 1
    `std::cin>>a;` will stop parsing as soon as it finds something that cannot be turned into a digit in an `int`. If the parsing stops immediately, nothing is extracted from the stream and the stream is placed into fail state. Depending on the C++ Standard you are compiling to you will either get a 0, newer Standards, or unchanged value, older Standards (this could be undefined behaviour. Can't remember, unfortunately). In the case of inputting j, instant failure, probably a zero value stored in `a`, and a failed stream. – user4581301 Apr 18 '22 at 05:40

3 Answers3

0

user4581301's comment points in the right direction.

One needs to understand better about the extraction operator (operator>>) in order to understand what is going on.

When assigning to an arithmetic type, the input is parsed character by character as long as the sequence of characters can be exactly interpreted as a value of that type. When it is no longer possible to do so, the parsing stops and the valid value that has been obtained till that point is used.

Thus there is no question of implicit conversion when just a character is entered and that of the character's ASCII value being assigned to an integer variable. Rather it is a failure and one can find the following sentence in the std::num_get<CharT,InputIt>::get link listed below.

If the conversion function fails to convert the entire field, the value ​0​ is stored in v.

The following are good places to get a broad understanding of this topic:

std::cin and handling invalid input

std::istream::operator>>

For a much more serious understanding, the following links are useful:

operator>>(std::basic_istream)

std::basic_istream<CharT,Traits>::operator>>

std::num_get<CharT,InputIt>::get, std::num_get<CharT,InputIt>::do_get

Hari
  • 1,561
  • 4
  • 17
  • 26
-1

The << operator works different depending on what is on the right hand side. In the first example it reads the char ‘5’ with a ASCII value of 53 and throws the ‘6’ away. In the second case it reads the int fifty-six. When you enter “J” that’s not an int, so trying to read an Int gets a result of 0.

And the >> operator does the same thing: When you output ‘5’ it’s written, it is written as a char, and the int 56 is written as an Int.

gnasher729
  • 51,477
  • 5
  • 75
  • 98
  • You mixed up the two operators. And the '6' is not thrown away but remains for the next input operation. – interjay Apr 18 '22 at 07:27
  • I don't think that the char `'5'` is read with an ascii value `53` as explained by Someprogrammerdude in the comments of my question in the 1st snippet. – Jason Apr 18 '22 at 08:16
-1

When istream operator<< expects something but gets something else, its failbit is set and in this state, the stream will not do anything.
So if there is a chain, it is stopped when a wrong input is met.
About handling this here.

But something else is also happening.
Since C++11, if extraction fails, zero is written to its value.

int a; // default-initializing fundamental type (no init / garbage value)
std::cin >> a;

If a char is encountered, a will become 0.

And also for integers, if the entered value is more or less than the type can hold, failbit is set and it will become std::numeric_limits<T>::max/min() or max() if T is unsigned.

MisaghM
  • 117
  • 4