C++ cin input stored directly to pass by reference variable - dangerous? - c++

Is it dangerous to have cin input directly assigned to a double variable that is passed by reference? If so, what measures can I take to defend against dangerous input - aside from not passing by reference.
Example below:
void samplefunction(double &var1, double &var2)
{
cout << "Enter something: ";
cin >> var1;
cout << endl;
cout << "Enter something: ";
cin >> var2;
}

The short answer, is no, as the cin >> operator will only read as much data as it requires to fill the type. The rest is discarded until the next whitespace. You may not get correct values, for example if someone feeds in "ABCDEF" instead of "1.0," but you won't have to worry about a buffer overflow.

Related

C++ second cin got eaten when the Input type isn't correct

I would like to ask a strange question.
double Test1, Test2;
cout << "Please Input the First Number: ";
cin >> Test1;
cout << "\nPlease Input the Second Number: ";
cin >> Test2;
cout << "\nHere is the Answer: " << endl;
cout << Test1 << Test2 << endl;
If my Input of Test1 is a char (for example 'A'), the second input will be eaten.
I've tried to use cin.ignore(numeric_limits<streamsize>::max()) and cin.ignore(numeric_limits<streamsize>::max(), '\n') but nothing seems to work.
Why is this problem happening?
The input with >> is terminated as soon as an invalid character is detected. That invalid character is not removed from the stream, so it's still there when you do the second >>.
The problem is that char type can not be converted to double by default.
Instead what you could do is declare both Test1 and Test2 as std::string type.
And if you want to convert them to double type, for example you are going to do some math calculation with them, you could do:
double d1 = std::stod(Test1);
Also you would need to #include <string> to use std::string.
Edit:
About why you never get to input the second time, when you enter 'A' for cin >> Test1, a fail flag was put onto you input stream. Because of that, all cin afterwards would not work unless the flag was resolved.
If you want to make it works again, you could add:
if(std::cin.fail())
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
after the first cin.
The cin.ignore() approach you tried was correct. However, you didn't reset the flag with cin.clear().

Writing a program in C++ that asks the user to enter values for all primitive types in C++

I am starting to learn C++ and I am trying to create a program that asks the user to add values for all primitive types in C++, here is what I have written so far:
#include <iostream>
using namespace std;
int main()
{
bool empty_bool;
char empty_char;
int empty_int;
float empty_float;
double empty_double;
cout << "Please enter a value for all inbuilt primitive types in C++" << endl;
cout << "Boolean:";
cin >> empty_bool;
cout << "Char";
cin >> empty_char;
cout << "Int";
cin >> empty_int;
cout << "float";
cin >> empty_float;
cout << "double";
cin >> empty_double;
}
The problem is that my program takes the input of boolean but then it just prints the rest of the variable names but it doesn't allow to take the value for the said variable and I can't figure out why, what am I doing wrong here?
After doing any input, cin will contain a result condition. Reading invalid input will put the input stream cin into a fail state; typically, you are supposed to check that by evaluating cin in a boolean context:
if (cin >> empty_int)
cout << empty_int; // empty_int here is not empty anymore
else
cout << "error";
When reading an inappropriately formatted value for bool (as mentioned in comments, it must be 0 or 1 or true or false depending on the boolalpha flag), cin remembers its error state, and will not do any further input until it is reset:
cin.clear();
Note by user4581301:
Note that clear does not remove the offending data from the stream. Depending on what was read and how before the failure, you probably have something in the stream that will cause the exact same error again. If so, remove it before continuing, using one of the following ideas:
use std::istream::ignore (like here)
read it into something permissive like a std::string
or whatever best fits your usage

Difficulty adding an enumerated variable into a structure variable with the dot operator in C++?

Essentially, I have a structure of VideoGame statistics
like the following in my C++ program:
struct Game
{
string title;
genre this_genre;
int this_rank;
float time;
};
I also have defined the enumerated type genre as this:
enum genre {FPS, MOBA, ROLEPLAY};
I have declared an abstract structure variable called NewGame
Game NewGame
My goal is the have the user define the members of the structure variable NewGame from standard input. I have no problem doing that for the other members of the structure, but I cannot seem to figure out how to get the user to store an enumerator in the enumerated member of the structure.
cout << "Enter the title for your game: ";
getline(cin, NewGame.title);
cout << "Enter the rank of your game: ";
cin >> NewGame.this_rank;
// The genre currently breaks the code:
cout << "Enter the genre of the game: ";
cin >> NewGame.this_genre;
cout << "Enter the time (days) spent playing your game: ";
cin >> NewGame.time;
I tried static casting it as an integer, but then I overloaded the insertion operator.
cin >> static_cast<int>(NewGame.this_genre); // doesn't work.
I want for the user to be able to provide values 0, 1, or 2, and have those respectively be assigned to FPS (0), MOBA (1), or ROLEPLAY (2).
What am I doing wrong? What am I not understanding?
You have to read into a temporary int and then use static_cast<genre> to get the enumeration value.
int value;
cin >> value;
NewGame.this_genre = static_cast<genre>(value);
You can "make your code work" with this:
cin >> reinterpret_cast<int&>(NewGame.this_genre); // bad
but don't do that, because it's undefined behavior to assign a value through such a type-punned reference.
Have the user input an integer, validate it, and then cast. The way you tried fails because you pass an rvalue to the insertion operator. static_cast<int> returns an integer, it doesn't transmogrify NewGame.this_genre into an integer for the type system.
int gen;
cin >> gen;
if(/*gen is valid*/)
NewGame.this_genre = static_cast<genre>(gen);

How to make the user type a value instead of storing a constant value?

I have made a simple program in C++ and this is the code:
#include <iostream>
using namespace std;
int main()
{
int number;
int square;
number = 5;
square = number * number;
cout << "The square is ";
cout << square;
return 0;
}
what it does is basically taking the integer "5" and get the square value on the screen and so on...
my question is:
how can I make the program take any value from the user instead of storing a value in the memory?
than Q.
Your code makes use of cout to print. C++ makes cin available for input from the console:
int x;
cin >> x;
"An example is worth a thousand words..."
Well cout takes some var. from memory and prints it out on the screen, right?
Well, cin does the exact opposite, it takes in some value from the keyboard and puts it in your memory..
You have to take in the value with the help of cin command, like this:
int a; //lets say you have a variable
cout << "Enter a value here: "; //prompts the user to enter some number
cin >> a; //this line will allow the user to enter some value with the keyboard into this var.
int square = a * a;
cout << "The square is: " << square;
Hope it helps...
Just replace:
number = 5;
with:
cout << "What's the number? ";
cin >> number;
You already know how to use cout to generate output, this simply uses cin to retrieve input.
Keep in mind that, while this may be okay for small test programs or learning, data input in real programs tends to be a little more robust (such as if you enter the string xyzzy when it's trying to input an int variable).

How can I cin an unsigned long long without error?

OK, so this is my code:
cout << "What is your p value?" << endl;
unsigned long long p;
cin >> p;
cin.ignore();
cout << endl;
cout << "What is your q value?" << endl;
unsigned long long q;
cin >> q;
cin.ignore();
cout << endl;
I put the first huge value--that is, p--in, and something gets put in to q automatically even with these cin.ignore()'s. What issues am I not seeing here? Please let me know if you need more information if it's not obvious to you.
[Adding information from a comment: the input value was 92896134244099469431, which exceeds 266.]
You say you entered a "huge value". If that value exceeds the upper bound of unsigned long long, then cin >> p; will fail.
A quick experiment indicates that once that happens, cin >> q; doesn't do anything, and no value is stored in q. The value of p will probably be 18446744073709551615, or 264-1.
You need to check whether each input operation succeeded or failed, and decide how to handle any errors.
You also need to update your question to indicate exactly what input you provided to your program.