Why does a string become an integer in C++? - c++

#include <iostream>
using namespace std;
int main () {
int N;
cout << " Input an integer:";
cin >> N;
cout << " The integer entered is:" << N << endl;
}
when I input an Integer it returns the same value but when I input hello it gives me 1961729588.

The string doesn't become an integer, the std::cin operation fails and what you get as output is the garbage value that was in N originally. Initialize N to 0, and type in "hello" you should see 0 as output.

"when I input an Integer it returns the same value but when I input hello it gives me 1961729588?."
The cin >> N; actually fails returning false for the stream state, when a input is given that cannot be converted to an integer. You can check for such error condition with
if(!(cin >> N)) {
cerr << "Input a valid number!" << endl;
}
else {
cout << " The integer entered is:" << N << endl;
}
The value of N will be initialized (reset) to int() (default value) which actually renders to 0.
Full live sample
#include <iostream>
using namespace std;
int main () {
int N;
cout << " Input an integer:";
if(!(cin >> N)) {
cout << "Input a valid number!" << endl;
cout << "N = " << N << endl;
}
else {
cout << " The integer entered is:" << N << endl;
}
return 0;
}
Input
Hello
Output
Input an integer:Input a valid number!
N = 0
This was cross checked with a Ideone code sample
I cannot reproduce getting some garbage value like 1961729588. The value was correctly reset by the std::istream& operator>>(std::istream&, int&); input operator.
Is it an issue of your current compiler's implementation, c++ standards level (-std=c++11) settings?
I have found some notes about eventual differences regarding c++ standards at cppreference.com:
Though I didn't spot what they really refer to with 'a value as described above', to be honest.

When you input a non-integer the input fails. When the input fails, N retains its original value which isn't defined, i.e., writing results in undefined behavior. You should test your inputs, e.g.:
if (std::cin >> N) {
// do something with the successful input
}
else {
// deal with the input failure
}

When you enter cin >> N; the compiler sees that N was declared as an int. Thus your program will call a function that will attempt to read text representing an int from cin and store the result in N.
To do this it will read as much numeric characters from cin as it can, and stop when a non-numeric character is encountered.
For example if you enter 32\n your program reads 3, then 2, then \n. When it sees the \n it stops reading, because \n is not a number. The program will push \n back on to the stream (in case we want to read it later) and store 32 in N.
Suppose instead of a number you type some word such as "hello". The your program will read h and then stop, because h is not a number. h will be pushed back onto the stream (to be read later) and nothing will be stored in N. cin will return an error since no numeric characters were read.
This still does not explain the value of 1961729588.
Notice N was never initialised. According to the C++ Standard the value of an uninitialised automatic variable is undefined. Thus the value of N will be some garbage value. In your case this was 1961729588.

Related

Validating Input C++ [duplicate]

This question already has answers here:
How to test whether stringstream operator>> has parsed a bad type and skip it
(5 answers)
Closed last year.
int num = 0;
while(true){
cout << "enter num: ";
cin >> num;
if(!(num)){
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "num must be an int" << endl;
}else if(num <= 0){
cout << "num must be greater than 0" << endl;
}else if(static_cast<double>(static_cast<int>(num)) != num){
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "num must be an int" << endl;
}else{
break;
};
};
I've been looking through SO and I found some threads that addressed similar issues, but nothing that is specific to what I'm trying to achieve. I'm only trying to accept integer inputs, no decimals, no strings, no characters. If I enter in a negative number or 0, it'll throw me an error saying "num must be greater than 0." If I enter in a, it'll throw me an error saying "num must be an int." If I enter 1.0, it'll throw me an error saying "num must be an int."
The problems I'm running into with this is when I enter in 0 for example, instead of executing the conditional statement that checks (num <= 0), it runs the conditional statement that says (!(num)). The other problem I'm running into is when I enter in a value that has a decimal, like 2.0, it'll truncate the numbers after the decimal and send in 2 as the value, completely glossing over the check to see if it's a decimal value and telling the program that it's a valid integer when it's not.
Does anyone have a solution for this, or an article link that solves problem like mines? Thank you!
This:
cin >> num;
if(!(num))
Should be this:
if (!(cin >> num))
You are checking the value of num when you should instead be checking the error state of cin. operator>> returns a reference to the input stream, which is then implicitly convertible to bool, where false means the stream encountered an error.
Also, this is completely useless:
else if(static_cast<double>(static_cast<int>(num)) != num)
Casting an int value to an int is a no-op, and casting an int value to a double back to an int will get you the original int value.
num is an int, it can't read in anything else. So, by the time your code reaches this point, you know num must be holding a valid int value. However, if the user had actually entered a floating-point number instead, operator>> would have stopped reading at the decimal point, leaving it and the remaining fractional value in cin's input buffer for later reading.
Also, the 2nd call to cin.ignore() is wrong. By that point, operator>> was able to read in an int value, it just wasn't satisfactory to you. So don't ignore subsequent input yet.
If you really need to differentiate between integer and floating-point input, you will have to read in the input as a string first, and then parse it to see what it actually holds, eg:
int num = 0;
string s;
size_t pos;
while (true){
cout << "enter num: ";
if (!(cin >> s)){
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "input error, try again" << endl;
}
else{
try{
num = stoi(s, &pos);
if (pos != s.size()) throw invalid_argument("");
if (num > 0){
break;
}
cout << "num must be greater than 0" << endl;
}
catch (const exception &){
cout << "num must be an int" << endl;
}
}
}
Online Demo

Why is my while loop function only returning '1'?

Precursor, I just started my first coding class, so forgive me if my mistake(s) is/are painfully obvious. All I need to do right now is use a programmer defined function to ask for an integer and read out an error message until the correct input is entered, then read out the correct input.
#include <iostream>
using namespace std;
bool evenint(int num1_par);//even integer declaration
int main ()
{
int num1, correctnum1;//even integer, function call variable
cout << "Enter an even integer between 2 and 12. \n";
cin >> num1;
correctnum1 = evenint(num1); //function call
cout << "You chose '" << correctnum1 << "'" <<endl;
return 0;
}
/*
Function: evenint
Parameter/Return: An even integer between 2 and 12 inclusively
Description: This function ensures the input matches parameters before
returning its value
*/
bool evenint(int num1_par)
{
if (!(num1_par>=2 && num1_par<=12 && num1_par % 2 ==0))// integer must be
between 2 and 12 inclusively
{
while (!(num1_par>=2 && num1_par<=12 && num1_par % 2 ==0))
{
cout << "Your number is invalid, please try again. \n";
cin >> num1_par;
}
return (num1_par);
}
else
{
return (num1_par);
}
}
I've tried switching my if-else/while loop to just a do-while/everything else I can think of but what I have now is the closest I've gotten. When I enter an invalid integer I get the correct response, but when I enter a valid integer it prints, "You chose '1'" no matter what valid integer I input. I've tried everything I know but now I'm stumped. Any help at all would be great!
Your function returns a bool which is either zero or one. Change it to int and your code will work.

unable to enter n in the below code( cin>>n)

/**
Write a program that reads a series of numbers and stores them in a vector. After the user inputs all the numbers he or she wishes to, ask how many of the numbers the user wants to sum. For an answer N. print the sum of the first N elements of the vector. For example: "Please enter some numbers (press 'I' at prompt to stop ) : " 12 23 13 24 15 "Please enter how many of the numbers you wish to sum, starting from the first:" 3 "The sum of the first 3 numbers : 12, 23, and 13 is 48." Handle all inputs. For exam ple, make sure to give an error message if the user asks for a sum of more numbers than there are in the vector.
**/
#include<iostream>
#include<vector>
using namespace std;
int main()
{
try
{
vector<int> numbers;
int num;
cout<<"Now enter the numbers";
while(cin>>num)
numbers.push_back(num);
int n,sum=0;
cout << "Enter the nth number to find sum of elements till n : ";
cin>>n;
if(n >numbers.size())
throw 66;
for(int i=0;i<n;i++)
sum+=numbers[i];
cout << "sum is "<<sum;
return 0;
}
catch(int k)
{
cerr<<"Error "<<k;
return -1;
}
}
So , when I enter EOF , CTRL+D , the program terminates. I am not sure where it is going wrong. I even tried to debug using gdb(with the help from an online tutorial) . It didn't just work out . can someone tell me what's wrong with the code ?
You are not checking if you actually read anything.
Consider this little test program:
#include <iostream>
int main()
{
std::cout << "std::cin is " << (std::cin ? "ready" : "done") << "\n";
int n = -42;
std::cin >> n;
std::cout << n << "\n";
std::cout << "std::cin is " << (std::cin ? "ready" : "done") << "\n";
n = -42;
std::cin >> n;
std::cout << n << "\n";
std::cout << "std::cin is " << (std::cin ? "ready" : "done") << "\n";
}
The output, when fed with an empty standard input (which is equivalent to immediately declaring its end with ctrl+d) is:
std::cin is ready
-42
std::cin is done
-42
std::cin is done
As you can see, n is never changed, as there is never a new value to change it to! Also, you can easily spot that the state of std::cin reflects if the previous read went past the end.
Since you are only checking the value of your integers without ensuring that they have a sane default (just check what happens to n if it is not set by reading the input), this can easily lead to your program exhibiting unexpected behavior.
Note: The behavior of the test program is different when fed input that simply is not a number.
When you supply cin with EOF it causes cin.failbit to become true. With the failbit set to true, all subsequent cin reads will be ignored. Since n has no default value execution becomes unpredictable from here. In my case the program was crashing because it was throwing 66. Adding cin.clear() after the while loop will fix this, but is not advisable. Two simple solutions would to stop on a magic number/prompt the user after every input if they want to continue.

Why does cin get strange values if input is a character and then stored in an integer in C++?

I am studying C++ and writing some code using these examples: http://doeaccmantra.blogspot.it/2013/09/doeacc-mantra-learning-point-blog-for.html
I have this code:
// http://doeaccmantra.blogspot.it/2013/09/doeacc-mantra-learning-point-blog-for.html
/*
* Prompt user for two integers and print their sum (Add2Integers.cpp)
*/
#include <iostream>
using namespace std;
int main() {
int integer1; // Declare a variable named integer1 of the type integer
int integer2; // Declare a variable named integer2 of the type integer
int sum; // Declare a variable named sum of the type integer
cout << "Enter first integer> "; // Display a prompting message
cin >> integer1; // Read input from keyboard (cin) into integer1
cout << "Enter second integer> "; // Display a prompting message
cin >> integer2; // Read input into integer2
sum = integer1 + integer2; // Compute the sum
// Print the result
cout << "The sum of " << integer1 << " and " << integer2
<< " is " << sum << endl;
return 0;
}
Could you Explain me why if cin is given a character as input, I have this result?
Enter first integer> s
Enter second integer> The sum of 0 and 4283950 is 4283950
I studied languages like PHP and JS where type mismatch is a Fatal Error..
Is this not the case for C++? So "s" is interpreted as a number?
Also, it seems that the code ignores the second cin in this case...
I think this question is to be closed, but I just want to clear this (interesting) one.
When you enter a letter the stream extraction fails and the stream is left in an error state. That also means both integer1 and integer2 are left uninitialized which explains why you see garbage values when they're used.
There are member functions to check the stream's state (good(), eof(), fail(), bad()). The simplest and, I think, more correct method is this:
if (cin >> integer1) {
// success
} else {
// failure
}
s is not read and assigned to your int. The value you see is what your var was before you tried to read the stream. Both calls to your stream fail as the stream remains in error and you will need to clear it before you can read it again.
Try this:
int integer1 = 0; // init your var
int integer2 = 0; // init your var
while (!(cin >> integer1))
{
cout << "Please enter a valid integer value";
cin.clear();
}

How to make cin >> not convert float to integer?

I have the following simple code:
#include <iostream>
int main()
{
int a;
std::cout << "enter integer a" << std::endl;
std::cin >> a ;
if (std::cin.fail())
{
std::cin.clear();
std::cout << "input is not integer, re-enter please" <<std::endl;
std::cin >>a;
std::cout << "a inside if is: " << a <<std::endl;
}
std::cout << "a is " << a <<std::endl;
std::cin.get();
return 0;
}
When I run the above code and input: 1.5, it outputs: a is 1. FYI: I compile and run the code with gcc 4.5.3.
This means that if cin expects an integer but sees a float, it will do the conversion implicitly. So does this mean that when cin sees a float number, it is not in fail() state? Why this is the case? Is it because C++ does implicit conversion on >> operator?
I also tried the following code to decide whether a given input number is integer following idea from this post: testing if given number is integer:
#include <iostream>
bool integer(float k)
{
if( k == (int) k) return true;
return false;
}
int main()
{
int a;
std::cout << "enter integer a"<< std::endl;
std::cin >> a ;
if (!integer(a))
{
std::cout << "input is not integer, re-enter please" ;
std::cin.clear();
std::cin >> a;
std::cout << "a inside if is: " << a <<std::endl;
}
std::cout << "a is " << a <<std::endl;
std::cin.get();
return 0;
}
This block of code was also not able to test whether a is integer since it simply skip the if block when I run it with float input.
So why this is the case when getting user input with cin? What if sometimes I want the input to be 189, but typed 18.9 by accident, it will result in 18 in this case, which is bad. So does this mean using cin to get user input integers is not a good idea?
thank you.
When you read an integer and you give it an input of 1.5, what it sees is the integer 1, and it stops at the period since that isn't part of the integer. The ".5" is still in the input. This is the reason that you only get the integer part and it is also the reason why it doesn't seem to wait for input the second time.
To get around this, you could read a float instead of an integer so it reads the whole value, or you could check to see if there is anything else remaining on the line after reading the integer.
When reading user input I prefer not to use operator>> as user input is usally line based and prone to errors. I find it best to read a line at a time and validate:
std::string line;
std::getline(std::cin, line);
This also makes it easy to check for different types of numbers.
std::stirngstream linestream(line);
int val;
char c;
if ((linestream >> val) && !(linestream >> c))
{
// Get in here if an integer was read.
// And there is no following (non white space) characters.
// i.e. If the user only types in an integer.
//
// If the user typed any other character after the integer (like .5)
// then this will fail.
}
Of course boost already supports this:
val = boost::lexical_cast<int>(linestream); // Will throw if linestream does
// not contain an integer or
// contains anything in addition
// to the integer.
Boost of course will convert floats as well.
I have some snippet which is kind a poor coding, but it works.
This method is pretty simple, but doesn't handle case when input value is invalid.
See more: https://en.cppreference.com/w/cpp/string/byte/atof
static float InputFloat(std::string label)
{
std::string input;
std::cout << label;
std::cin >> input;
return atof(input.c_str());
}
int main()
{
float value = InputFloat("Enter some float value: ");
std::cout << "value = " << value;
return 0;
}