cin erratic behaviour - c++

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

Related

Unable to read two strings with cin.get()

Why does trying to input two strings using cin.get() fails? I can successfully read the first string but the input fails for second string and subsequent operations.. See the code:
#include <iostream>
#include <stdlib.h>
int main(){
long int n,k;
char a[11],b[11];
cin.get(a,11);
n = atoi(a);
cin.get(b,11);
cout<<b;
k = atoi(b);
cout << "\ncin.rdstate(): " << cin.rdstate()
<< "\n cin.eof(): " << cin.eof()
<< "\n cin.fail(): " << cin.fail()
<< "\n cin.bad(): " << cin.bad()
<< "\n cin.good(): " << cin.good() << endl << endl;
}
I am trying to input two strings and store them into long int variables as shown in program, but the cin.get(b,11) fails and stack overflow occurs for
k= atoi(b) .Also, you may observe nothing is output for cout<<b .. And, at last cin.fail() is set to 1 , which means I am doing some kind of logical error.. Please help me in rectifying this!
Please suggest some method which is fast and meant for c++ only ..
(If you feel this question is too bad please mention in comments before down voting this, I am already struggling at 21 rep!)
\n will remain in the buffer after the first cin. You can solve this problem by adding an empty cin.get()
cin.get(a,11);
n = atoi(a);
cin.get();
cin.get(b,11);
cout<<b;
k = atoi(b);
cin.get() Does not extract the delimiter from the input (documentation).
If you are C++ with streams it makes sense to use the built in functionality. In particular, C++ offers formatted I/O. To read two numbers you should use:
long int a, b;
cin >> a;
cin >> b;
This will read two numbers from the standard input.
If speed is a concern, try to turn off C I/O synchronisation: std::ios::sync_with_stdio(false); There is an interesting benchmark here that shows that if you turn of synchronisation with C I/O, streams are actually pretty fast.

why std::cin doesn't give error on "char"

Here is a small code:
char a;
while(std::cin >> a) {
std::cout << a << " is pressed\n";
}
When I type in "w", i get "w is pressed".
When I type in "www", i get "w is pressed" 3 times in a row.
Can someone please explain why this happens?
Thanks
When you use std::cin to read a char variable it reads one character at a time. That is why you get 3 iterations in the while loop for input www.
There is a queue of inputs. if you entered too much, your input waits in patient...
The first part of the answer is on the first line of your code.
char a;
Variable a is a single char, an 8-bit value typically used to store a code representing a display character. If the display is ASCII, then (value) 0 = no character, (value) 32 = space, value 48 = (character) '0', etc.
std::cin is an instance of class std::istream, it has various members and operator overloads to deal with different types. In the case of a char, you are calling
std::istream::operator(char)
Which reads one char, exactly one, from the input stream and returns.
#include <iostream>
int main()
{
char a, b, c;
std::cin >> a >> b >> c;
std::cout << "a = " << a << ", b = " << b << ", c = " << c << '\n';
return 0;
}

why it always give zero output?

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

infinite loop in c++ [duplicate]

This question already has answers here:
Infinite loop with cin when typing string while a number is expected
(4 answers)
Closed 3 years ago.
I'm learning C++ and writing little programs as I go along. The following is one such program:
// This program is intended to take any integer and convert to the
// corresponding signed char.
#include <iostream>
int main()
{
signed char sch = 0;
int n = 0;
while(true){
std::cin >> n;
sch = n;
std::cout << n << " --> " << sch << std::endl;
}
}
When I run this program and keep inputs at reasonably small absolute values, it behaves as expected. But when I enter larger inputs, e.g., 10000000000, the program repetitively spits out the same output. Some combinations of input cause erratic behavior. For example:
#: ./int2ch
10
10 -->
10000000000
10 -->
10 -->
10 -->
10 -->
The program spits out "10 --> " until it's killed. (With this particular sequence of inputs, the program's output changes speed erratically.) I also noticed that the output of large values is determined by the previous legal input as well as the value of the current illegal input.
What's going on? (I don't care about fixing the program, that's easy. I want to understand it.)
Basically your cin stream is in a fail state and thus returns immediately when you try to read it. Rewrite your example like this:
#include <iostream>
int main()
{
signed char sch = 0;
int n = 0;
while(std::cin >> n){
sch = n;
std::cout << n << " --> " << sch << std::endl;
}
}
cin >> n will return a reference to cin, which you can test for "good-ness" in a conditional. So basically the the "while(std::cin >> n)" is saying "while i could still read from standard input successfully, do the following"
EDIT: the reason it repeatedly output the last good value entered is because that was the last value successfully read in n, the failed reads won't change the value of n
EDIT: as noted in a comment, you can clear the error state and try again something like this would probably work and just ignore bad numbers:
#include <iostream>
#include <climits>
int main() {
signed char sch = 0;
int n = 0;
while(true) {
if(std::cin >> n) {
sch = n;
std::cout << n << " --> " << sch << std::endl;
} else {
std::cin.clear(); // clear error state
std::cin.ignore(INT_MAX, '\n'); // ignore this line we couldn't read it
}
}
}
Yes, Evan Teran pointed out most things already. One thing i want to add (since i cannot comment his comment yet :)) is that you must put the call to istream::clear before the call to istream::ignore. The reason is that istream::ignore likewise will just refuse to do anything if the stream is still in the fail state.
Given that you are on a 32 bit machine, 10000000000 is too big a number to be represented by an int. Also converting an int to a char will only give you from 0..255 or -128..127 depending on the compiler.
One problem here is that a char has a size of one byte, and thus can only hold a number between -127 and 128. An int on the other hand, is typically 4 bytes, and can take on much larger values. Second problem is that you are inputting a value that is too large even for an int.

Input a letter to 'int'

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