Code:
int a;
cin>>a;
cout<<a<<endl;
Then I use g++ test.cpp, and run it. Then I input a letter 'b' to the variable a. The output is 0.
But, When I test the Other code:
cout<<int('b')<<endl; // output: 98
Why? What is the different?
std::cin is an object, an instance of a std::istream. std::istream has overloaded the >> to support a variety of types. One of those types is &int. When there is a std::istream on the left of >> and an integer reference on the right, the method istream& operator>> (int& val) is called. The conceptual implementation of that method is as follows.
Store 0 in an accumulator
Read a character of the input
If the character is 0-9, add its decimal value to the accumulator
If not, return the value of the accumulator
Return to step 2
When you provide 'b' as input to istream& operator>> (int& val), it immediately stores the "accumulated" 0 in your int variable. Example:
#include <iostream>
int main (const int argc, const char * const argv[]) {
int b = 100;
std::cout << b << std::endl;
std::cin >> b;
std::cout << b << std::endl;
return 0;
}
Execution:
100
b
0
As for the cast, when you cast the value 'b' to an integer, you already have a byte in memory with the value 98, which you then print as an integer. When you use >> the resulting value in memory is 0, which you then print as an integer.
The input operation that you are trying to do is failing. Since a is an int cin expects an int. since it gets a char it fails. You can test this by changing you code to:
int a;
cin>>a;
if(!cin)
cout << "input failed";
else
cout<<a<<endl;
Input:
a
Output:
input failed
See this live example
When you are using 'b' to cin a integer value, your program think you are input a invalid number, so it does't assign value by int('b'). still using initial value of a
not sure if this what you're finding:
char a;
cin >> a;
cout << a << endl;
try to change int to char,
when you enter 3, it'll output 3;
when you enter b, it'll output b;
if you want to output ascii, you can make cout like:
cout << (int) a << endl;
then you'll get 98 when you enter b
If extraction fails (e.g. if a letter was entered where a digit is
expected), value is left unmodified and failbit is set. (until C++11)
If extraction fails, zero is written to value and failbit is set. If
extraction results in the value too large or too small to fit in
value, std::numeric_limits::max() or std::numeric_limits::min()
is written and failbit flag is set. (since C++11)
from https://en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt
Related
I was working on a HackerRank problem and I could not figure out why the C++ code round the double values when I am adding them and why it does not take in/print the entire string input it is given.
The code is supposed to take in an integer input (from one line), a double input (from another line), and a string input (also, from another line). Then it is supposed to print out the sum of the int input and 4, the sum of the double input and 4.0, and concatenate the string "HackerRank" to the beginning of the input string.
Here's the code I have:
#include <iostream>
#include <iomanip>
#include <limits>
int main(){
int i = 4;
double d = 4.0;
string s = "HackerRank";
// Declare second integer, double, and String variables.
// Read and save an integer, double, and String to your variables.
// Note: If you have trouble reading the entire string, please go back and review the Tutorial closely.
// Print the sum of both integer variables on a new line.
// Print the sum of the double variables on a new line.
// Concatenate and print the String variables on a new line
// The 's' variable above should be printed first.
int a;
double b;
string c;
cin >> a;
cin >> b;
cin >> c;
a = a + i;
b = b + d;
cout << a << endl;
cout << b << endl;
cout << "" + s + c;
return 0;
}
For the following input:
12
4.0
is the best place to learn and practice coding!
I got the output:
16
8
HackerRank is
When this is the expected output:
16
8.0
HackerRank is the best place to learn and practice coding!
The answer to your 2 questions:
Firstly, when you add a value of type int to a value of type float/string, the result will be of type int. This explains why you the output is 8 and not 8.0. This same rule applies to multiplication, division, and subtraction. Whenever an int is operated on by a float/double value or vice versa, the result is always of type int. Therefore, you should change the initialization of your d value to:
double d = 4.0; // Or float d = 4.0
By the way, you cannot add a decimal point to a value of type int and expect it to be a floating point/double value. The data type of the variable that stores the value must be defined/initialized with a certain data type.
Secondly, your code does not print the desired string as you are using the wrong function to get the string as input from the user. While cin is the norm to be used in input, it does not work so well with variables of type "string". The reason for this is because cin only accepts one word; one continuous int, floating point value, char, etc..., and it cannot accept an entire sentence with spaces in between because it just stops reading after it sees a space; that's the rules of cin. To bypass this problem, you'll need another function, and that is
getline(cin, variable_to_store_data);
instead of doing:
cin >> c;
Do this:
getline(cin, c);
This way, the entire sentence you inputted will be stored in the variable and not just the first word of the sentence. The getline does not ignore the words in a sentence that come after the first one; it reads all of the user input till the point he/she hits Enter, and it then stores the entire value in the variable (that's the second parameter).
By the way, if you want to output multiple things in one cout line, then do it using the following template:
cin << a << ... << z << endl; // endl is optional; depends on your needs
Avoid using the method you used above:
cout << "" + s + c;
Do it this way:
cout << "" << s << c; // Why do you have "" at the begninning? That prints nothing. You can take that off also.
On a side note, getline() also has a lot of other functions, such as reading lines from a file. Read more about it online; there are lots of resources available.
Hope this answers your question.
EDIT: To make the program work, you'll actually have to add another line to ignore the enter hit at the end of the cin >> b; command, because that saves as the string in c. Therefore, do this:
cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
getline(cin, c);
The line I just added ignores the newline character hit at the end of the cin >> b command. This way, the compiler goes on to ask the user for the string to be stored in c. I've tried this code, and it works as it should.
Another thing, change your output statement to;
cout << "" << s << " " << c << "." << endl;
This makes the string easier to read, and it adds a space between variable s and variable c during output. Hope this helps!
This code will work...
#include<iostream>
#include<string.h>
using namespace std;
int main()
{
int i = 4;
double d = 4.0;
string s = "HackerRank ";
int i2;
double d2;
string s2;
cin>>i2;
cin>>d2;
cin.ignore();
getline(cin, s2);
cout<<i2+i<<endl;
cout.precision(1);
cout << fixed << d+d2 << endl;
cout<<s+s2;
return 0;
}
You can use the function 'getline' to realize it.
And the following example is well done on VS2013.
#include <string>
#include <iostream>
using namespace std;
int main(){
string c;
getline(cin, c); // is there anybody ?
cout << "Hello, " + c; // Hello, is there anybody ?
system("pause");
return 1;
}
cin>>b;
use cin.ignore();
and then getline(cin, string_name);
This will read the complete string.
I am curious why cin behaves in the following way. I think I might have
some misunderstanding about its behavior.
Consider this simple code. This code is asks for some input to be entered, all of which is printed out in the last statement.
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char** argv) {
cout << "Please enter your input: " ;
int a=3, b=87; // initialized to some random integers
string s = "Mary" ; // initialized to a random string
cin >> a ;
cin >> b ;
getline(cin,s);
cout << "You entered the following " << a << " " << b << " " << s << endl;
return 0;
}
Now if the input is 12 34 cat the output is 12 34 cat
This is expected.
However if the input is cat 23 dog the output is 0 87 Mary.
Here is why I think this is unexpected:
cin >> a should fail since catcannot be converted into an integer. However, a gets replaced with what I presume is a garbage value.
Now since the second number of the input is an integer 23, cin >> b must succeed. Yet this operation seems to fail, and b continues to retain its original value unlike what happened to a.
Similarly getline fails to place the string <space>dog into the string s
which continues to retain its original value of Mary.
My questions are the following.
Does the failure of some cin operation mandate the failure of all
subsequent cin operations using the >> operator or the getline function.
Why did the failure of the first cin operation change the value of a
whereas the initial values of b and s were unchanged?
Does the failure of some cin operation mandate the failure of all
subsequent cin operations using the >> operator or the getline
function.
Yes. Until you clear the error with cin.clear(). Also, when an extraction fails, the characters are left in the buffer, so if you try to read the same type again, it will fail again.
Why did the failure of the first cin operation change the value of a
whereas the initial values of b and s were unchanged?
Because (since C++11), it is defined to change the value to 0 in case of failed extraction from a (previously) valid stream. Before C++11, it would have been left unchanged. For a stream in an error state, the operation does nothing, which is why b and s are unchanged.
Does the failure of some cin operation mandate the failure of all subsequent cin operations using the >> operator or the getline function.
Yes. Your code expects to read the input value in exactly that order
cin >> a ; // 1st integer value
cin >> b ; // 2nd integer value
getline(cin,s); // string value
Giving it a input like
cat 23 dog
leads to setting fail() state on cin when trying to read the 1st int value, and none of the following operator>>() calls will succeed.
cin >> a should fail since catcannot be converted into an integer. However, a gets replaced with what I presume is a garbage value.
It's no garbage value but well defined, see the reference citation below.
Now since the second number of the input is an integer 23, cin >> b must succeed. Yet this operation seems to fail, and b continues to retain its original value unlike what happened to a.
No this assumption is wrong, as mentioned cin is in fail() state at this point, and parsing further input is skipped at all.
You have to call clear() after each operator>>() call, to be sure the input will by parsed:
cin >> a ; // 1st integer value
cin.clear();
cin >> b ; // 2nd integer value
cin.clear();
getline(cin,s); // string value
Why did the failure of the first cin operation change the value of a whereas the initial values of b and s were unchanged?
Because the reference of std::basic_istream::operator>>() says
"If extraction fails, zero is written to value and failbit is set. If extraction results in the value too large or too small to fit in value, std::numeric_limits<T>::max() or std::numeric_limits<T>::min() is written and failbit flag is set. (since C++11)"
You should use cin.good() function or shorthand notation if(cin) as said by #AndyG to check the state of cin object. variable a is of type int then how can you & why are you inputting string? So, it gives unexpected output for variable a.
char input1;
std::cout << "input1 : ";
std::cin >> input1;
int input2;
std::cout << "input2 : ";
std::cin >> input2;
std::cout << input1 << std::endl;
std::cout << input2 << std::endl;
return 0;
I wrote 'a' at input1 and 'a' at input2.
Ouput is like this.
input1 : a
input2 : a
a
-858993460
I'm curious...'a' charter is 97 in dec. why does it print -858993460?
'a' is not converted to 97 automatically? why?
a, as a string, is not convertible to an int by the rules std::cin follows. Consider this: a is not a valid integer in base 10. std::cin will fail to convert the string "a" to an int.
The reason it prints -858993460 is because the int is not initialized, so it could print anything, or nothing, or do whatever it desires (look up undefined behaviour).
Try something like this instead:
char input2_chr;
std::cin >> input2_chr;
int input2 = input2_chr;
I think the input simply failed, and the value you're seeing is the result of undefined behavior (input2 was never written to).
If you try to read an integer, the character 'a' is not valid so it wouldn't be accepted by the >> operator.
You seem to somehow expect that the input should convert the character to the ASCII code for that character in order to give you the integer-typed result you requested. This reasoning is not supported by the language.
In the first, you asked to input a character, so you got the first
non-whitespace character in the stream. In the second, you asked to
input an integer, so the stream skips whitespace (as it always does with
>>) and attempted to parse an integer. Since "a" cannot be the
start of an integral value, the stream set an error status (the
failbit) and returned, without modifying input2. When you output
the uninitialized variable, you have undefined behavior. (You should
never use a variable you've input without first checking whether the
input succeeded or not.)
From what you describe, it sounds like you are trying to input some
binary format. To do that, you must open the stream in binary mode,
ensure that it is imbued with the "C" locale, and then use
istream::get or istream::read. (Of course, you have to know what
the binary format is that you are reading, in order to be able to
convert the unformatted bytes you read into the actual information you
need.)
As e.g. Aardvard already has answered, you're seeing an arbitrary original value, in the C++ standard called an indeterminate value, because the input operation failed and input2 was not assigned a new value.
To output a decimal representation of the value of a char variable, simply convert it to int in order to direct the output stream to treat as integer.
The easiest way to convert it to int is to encourage an implicit promotion by using the variable in an expression, such as simply adding a + sign in front of it:
#include <iostream>
using namespace std;
int main()
{
char const ch = 'a';
cout << "'" << ch << "' = " << +ch << endl;
}
Output:
'a' = 97
Because you are reading an integer at input2. a isn't an integer. Therefore nothing will be read, and the original value of input2 will be maintained.
In this case, it will be some random value, cause input2 isn't initialized.
You can check whether the read succeeded by checking cin.good()
int i;
cin>>i;
cout<<i
when we entered Character i.e 'A' why it gives Zero output ?
Because A is not a numeric value suitable for storing in an integer, so it will leave your integer alone, as shown here:
#include <iostream>
int main (void) {
int i = 12345;
std::cin >> i;
std::cout << i << std::endl;
return 0;
}
When you run that code and enter A, it outputs 12345 as the value doesn't change.
If you want truly robust input, it's usually better to input lines as strings then convert them yourself.
"Mickey-mouse" programs or those where you have total control over the input can use the sort of input methods you're using, serious code should use more suitable methods.
If your intent is to convert an input character into its integer code, you can use something like:
#include <iostream>
int main (void) {
char c;
std::cin >> c;
std::cout << (int)c << std::endl;
return 0;
}
You should always check if the operation succeeded before continuing.
int i;
if (cin >> i)
cout << i;
else
cout << "Not a valid number!";
because the value 'A' is not stored in the variable i since it is a integer variable. i believe that is the reason the initial value 12345 is printed on the screen...
I'm a newbie to C++. Small code sample follows:
int main(int argc, char* argv[]) {
char ch1;
int int1;
cin >> ch1;
cin >> int1;
cout << ch1 << '\n';
cout << int1 << '\n';
return 0;
}
When I run the program and input the following:
az
I get as output:
a
32767
I understand the 'a' but why the integer value of 32767? I just want to test and see what happen if instead of a numeric value assigned to int1 i used a 'z'.
I try inputting:
ax
...and I also get same results.
Now if instead of int int1 I use short int1 and run the program with input:
az
I get the output:
a
0
P.S.
sizeof(int) = 4
sizeof(short) = 2
I am using a 64-bit machine.
When an input stream fails to read valid data, it doesn't change the value you passed it. 'z' is not a valid number, so int1 is being left unchanged. int1 wasn't initialized, so it happened to have the value of 32767. Check the value of cin.fail() or cin.good() after reading your data to make sure that everything worked the way you expect it to.
cin >> int1; means "read an integer and put it in int1." So you feed it z, which is not a valid character in an integer, and it simply aborts the read and leaves whatever in int1.
Test this by initializing int1 to something and seeing what happens.
The c++ cin stream is doing input validation for the program.
When streaming from cin into an int cin will only accept valid number didgits, -0123456789, and also only values between INT_MIN and INT_MAX.
If the numerical value for z (122) is required I would recommend using the c getchar function rather than the cin stream.
int main(int argc, char* argv[]) {
cout << "function main() .." << '\n';
char ch1 = getchar();
int int1 = getchar();
cout << ch1 << '\n';
cout << int1 << '\n';
return 0;
}
When az is input this will output
a
122
Using cin directly is, personally, i.e., for me, a bad idea for reading data in non-trivial programs. I suggest you read another answer I gave for a similar question:
C++ character to int