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()
Related
{
int n;
cin>>n;
cout<< n;
}
The output is 0 when any alphabet or special character is given as input.
In C its not the case when I used scanf(); and printf(). It prints the corresponding ASCII value.
Please explain why is this happening?
Please explain why is this happening?
In the documentation of the std::istream& operator>>(std::istream&, int) it's stated (emphasis mine):
If extraction fails (e.g. if a letter was entered where a digit is expected), value is left unmodified and failbit is set.
For c++11 code it seems initialization is guaranteed:
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.
Assumed you run a debug build of your code, n is probably initialized with 0 automatically, but technically accessing it is undefined behavior, since it wasn't initalized in that case you describe.
You have to check cin's state after input to detect if a failure occured during the number extraction, or if you can safely use the now-initialized value:
int n;
std::cin >> n;
if(std::cin) {
std::cout << n << std::endl;
}
else {
std::cin.clear(); // Clear the streams fail state
std::string dummy;
std::cin >> dummy; // Consume the non numeric input
std::cout << "Wrong input, '" << dummy << "' is not a number."
}
In both C and C++, when inputting an integer, the driver input function will read numeric characters until a character that is not a number is read.
For example, the sequence "123GHI" should return the value 123.
I have a little "blackjack" program coded in C++. The thing is that the program asks questions like "Would you like... (y/n)?" where user needs to type y/n. I want to check if the value returned is actually the type that I want. So function that should return int, returns int and function that should return char, returns char, before it actually returns something.
I would need some suggestions guys. I think it's not that difficult, I just can't find any solution. Thank you.
Code:
char pickCard(){
char aCard;
std::cout << "Would you like another card?";
std::cin >> aCard;
if (aCard is a char){
return aChar;
} else {
std::cout << "Not a char!";
}
}
I think you have a misconception of exactly how std::istream's formatted input works. In your example, aCard must be a char, because you've declared it as such. If the use enters more than one character, one character will be put into aCard, and std::cin will hold onto the other characters and give them to you the next time you call operator>> (or any other input function); if the user enters a number, aCard will be the character representation of the first digit of that number.
Keep in mind that operator>> knows what type of variable you've given it, and it will ensure that the user's input is valid for that type. If you give it an int, it will make sure the users input is convertible to an int or give you 0 if it isn't. A variable can never be anything but the type you declared it to be.
If you're interested in chars in particular, there's a whole bunch of character classification functions you can use to tell what sort of character (letter, digit, whitespace, etc.) you're working with, but keep in mind that char foo('4') is entirely different than int foo(4).
I guess you just want to know if the input string is in number format. >> will set the istream's failbit if it cannot convert the input string to int.
int num;
if (cin >> num) { // input is "123abc", num == 123
cout << "yes, input is a number. At least start with some figures. "
cout << "num == " << num;
} else { // input is "abc" , error
cout << "no, input is not a number or there is some kind of IO error."
}
If you want to force y or n as only allowed characters you can do:
char pickCard(){
std::string response;
std::cout << "Would you like another card?";
std::cin >> response;
if (response=="y" || response=="n"){
return response[0]; //or anything useful
} else {
std::cout << "Not a char!";
//... more code here
}
//... more code here
}
you can use length() property of std::string to find its length. a string of length one is a char in most cases.
Why doesn't the function print "true" when '1' is input for both variables? How can I fix this?
int main() {
int i;
char c;
cout << "Type int: ";
cin >> i;
cout << "Type char: ";
cin >> c;
if (i == (int)c)
cout << "true" << endl;
else
cout << "false" << endl;
}
Even though char is an integer type, it is treated by the >> operator differently from other integer types.
For non-char integer recipient variable the >> operator treats the input as a representation of an integer value. The entire representation is consumed from the input, converted to integer and stored in the recepient variable. For example, if you enter 8 as the input, the recipient variable (say, an int) will receive integer value 8. If you enter 42 as the input, the recipient variable will receive integer value 42.
But for char recipient variable the >> operator treats the input as a mere character sequence. Only the first character of that sequence is consumed and immediately stored in the recipient variable. For example, if you enter 8 as the input, a char recipient variable will receive character '8', which corresponds to integer value of 56. If you enter 42 as the input, the recipient variable will receive character '4', which corresponds to integer value of 52.
That is what leads to the inequality in your case.
Like other input stream objects, std::cin is designed to work differently when you read into different types.
For an int, it reads the numbers you write into the console and parses them into internal integer form. This is convenient: "formatted extraction" means we get a useful int right away and don't need to any conversions from string to number.
For a char, it reads the actual letter or digit or punctuation that you wrote into the console; it does not parse it. It simply stores that character. In this case, c is 49 because that is the ASCII value of '1'.
If you wanted to see whether the int contained 1 and the char contained '1' to match, then you can exploit the property of ASCII that all the digits are found in sequential order starting from 48, or '0':
if (`i` == `c`-'0')
However, if you do this, you should verify that:
Your platform uses ASCII;
c contains a digit ('0', '1', ..., '9').
Generally avoid these hacks if you can. There's usually another way to check your inputs.
Example:
int i=0;
do {
cin >> i;
if(!isdigit(i)) cout << "Error. Must be an integer\n\n";
}
while(cin.fail());
If a character rather than an integer was input by the user, the program would break and go into some infinite loop for some reason. Why is this? Is there no way to prevent it from happening? the isdigit() function doesn't seem to work well with int variables, only with char variables.
You seem to be confused about how input works. When you write
std::cin >> i;
and i is an int, the input stream will extract the text for
an integral value: it will skip whitespace, then extract
a possible sign, then one or more digits. It will then convert
this text into an int, and store it where requested. If it
doesn't find text in the appropriate format, it will set an
error status (failbit), which will remain set until you clear
it. And it will not modify i; you must always check that
input has succeeded before using the variable input.
isdigit, on the other hand, has undefined behavior unless
the integer it is passed is in the range [0,UCHAR_MAX]. (Note
that range. It means that you cannot simply pass it a char.)
It's not clear what you're trying to do here. If it's just
enter an int:
int i;
while ( !(std::cin >> i) ) {
std::cout << "Error: integer wanted" << std::endl;
std::cin.clear(); // Clear error...
std::cin.ignore( INT_MAX, '\n' ); // And ignore characters which caused it
// (up until next '\n')
}
If you want a single digit:
int i = std::cin.get();
while ( i != EOF && !isdigit( i ) ) {
std::cout << "Error, single digit wanted" << std::endl;
i = std::cin.get();
}
char ch = i; // NOW (and only now) can you convert into int.
std::cin.get() returns an int, in order to handle the out of
band value EOF. The int in guaranteed to be in the range
[0...UCHAR_MAX], or to be EOF, so you can pass it directly
to isdigit. Only once you've finished these tests should you
convert it into a char (since a digit is a character).
You always need to check after reading that your input was successful, e.g.
if (std::cin >> i) {
// process input
}
If the input fails std::ios_failbit is set. While this flag is set the stream won't accept any input and convert to false. To clear the error flags you use
std::cin.clear();
Clearing the error flags won't remove the offending character. You'll need to get rid of them, e.g., using
std:: ignore();
The above code certainly doesn't create an infinite loop. But the loop happens usually when a digit is expected and a non-digit is given, so the characters in the buffer will stay there and the stream is in an bad state. This will happen until the stream is appropriately cleared, so that the stdio can continue to read according to the format specification. Of course the loop has to be done iny our program, as stdio is not looping on it's own.
To clear the input and ingore what is left there you can use this:
std::cin.clear();
std::cin.ignore();
I was working on the following code.
#include <iostream>
int main()
{
std::cout << "Enter numbers separated by whitespace (use -1 to quit): ";
int i = 0;
while (i != -1) {
std::cin >> i;
std::cout << "You entered " << i << '\n';
}
}
I know that using while (std::cin >> i) would have been better but I don't understand a specific occurrence.
If I provide an invalid input, the loop becomes infinite because the Input Stream enters a failbit state. My question is that what happens to the input variable i? In my case, it becomes 0 regardless of the previous value entered. Why does it change to 0 after an invalid input? Is this a predefined behaviour?
You get zero because you have a pre-C++11 compiler. Leaving the input value unchanged on failure is new in the latest standard. The old standard required the following:
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.
(source)
For gcc, you need to pass -std=c++11 to the compiler to use the new behavior.