问题
I'm a beginner programmer in C++ (currently), and I've got a conceptual question.
I'm trying to filter a cin
input to ensure that it is a one-or-two-digit integer between 01-04, and if it isn't, to produce an error and ask for a new input.
I'm also using map
to give the user a list of options that, upon valid selection, routes inputs (integers) through any of several methods to produce a relevant result, but I'll ask a more specific version of this question elsewhere.
I found a snippet of code at http://www.cplusplus.com/forum/beginner/26821/ that is meant to validate an input. I sort of get it, except where the boolean condition is set inside the while loop. Because I don't understand it, it makes it very difficult to edit or make sure that I'm manipulating it right.
Here is the example code:
int main()
{
int num;
bool valid = false;
while (!valid)
{
valid = true; //Assume the cin will be an integer.
cout << "Enter an integer value: " << endl;
cin >> num;
if(cin.fail()) //cin.fail() checks to see if the value in the cin
//stream is the correct type, if not it returns true,
//false otherwise.
{
cin.clear(); //This corrects the stream.
cin.ignore(); //This skips the left over stream data.
cout << "Please enter an Integer only." << endl;
valid = false; //The cin was not an integer so try again.
}
}
cout << "You entered: " << num << endl;
system("PAUSE");
return 0;
And here is my code (the entire thing, to give context). I don't think it's complete, I just want to make sure I'm using the boolean right.
float _tmain(float argc, _TCHAR* argv[])
{
bool validInput = !true;
map<string,int> Operations;
Operations.insert(pair<string, int>("Addition", 01));
Operations.insert(pair<string, int>("Subtraction", 02));
Operations.insert(pair<string, int>("Multiplication", 03));
Operations.insert(pair<string, int>("Division", 04));
cout << "Welcome to OneOpCalc, what operation would you like to perform?" << endl;
for(map<string, int>::iterator ii=Operations.begin(); ii!=Operations.end(); ++ii)
{
cout << (*ii).second << ": " << (*ii).first << endl;
}
while (!validInput)
{
cin >> operatorSelection;
if (cin.fail() || operatorSelection < 4 || operatorSelection > 1)
{
cout << "Error: Invalid selection. Please choose a valid number." << endl << endl;
cin.clear();
cin.ignore();
}
}
}
Does while (!valid)
mean "While valid
is false"? In my head, it's saying "While valid
is !valid
", which obviously, would always be false.
EDIT: Thanks for the answers guys, I'm looking through them all. One answer I keep getting goes too general; I understand that ! is NOT, and I understand the concept of flipping the bool using it. However the implicit logical implications are what confuse me. In any given statement, I am used to thinking of !valid
as a way of flipping the valid
value; Not testing a condition. It's the syntax of using it to test a condition that tricks me. In other words, writing while(!valid)
reads literally to me as while(NOTvalid)
, not while(valid==false)
. I can't get myself to understand why in this case, !valid
reads as a condition and not just a bit-flip.
回答1:
Loops (and ifs) are controled by an expression of type bool
.
In while ( !valid )
, the expression is !valid
, the operator
not applied to the value of the variable valid
.
while ( !valid )
means (literally) while the expression
!valid
(which means "not valid") is true.
For the rest, the code you're copying is pretty bad. I wouldn't use it as an example if I were you.
As for your own code:
_tmain
is very particular to Microsoft. You don't want to use it. If your writing a console application, just usemain
. (Same thing holds for_TCHAR
, rather thanchar
.)Neither
_tmain
normain
can return afloat
. The return type ofmain
should always beint
. I'm less familiar with_tmain
, but it's eitherint
orvoid
. (Probablyint
, if you're in a console mode program.)!true
isfalse
. Always. (Programming is different than the real world. There are no maybes.) Why be more complicated than necessary?There's no need for the flag variable at all. You can just write:
cin >> operatorSelection; while ( !cin || operatorSelection > 4 || operatorSelection < 1 ) { // ... }
In case of error, you currently only ignore a single character. You probably want to ignore up to and including the end of line. (
std::cin.ignore( std::numeric_limits<std::streamsize>::max() );
.And the condition in your if will always be true. (See my version above.) Where do you expect to find a number which is neither less than for nor greater than one?
回答2:
In your code, inside the loop, just add:
else
validInput = true;
after the if
closing bracket.
You want to get out of it once the user has typed a correct value.
回答3:
You want to run the loop "while there is not a valid input". Remove the non-bold words, and translate to C++.
Of course, the second case is not working, because nothing changes validInput
inside the loop, so it stays "invalid", and the loop continues forever (And if you want to set something to false
then bool validInput = !true;
is more convoluted than bool validInput = false;
- the compiler will do the same thing, but someone reading the code will have to think to see what it does - it is a good thing to think when reading code, but it's not a good thing to write code that is more complicated than necessary...).
回答4:
A while loop has a condition and a body, the body is executed as long as the condition evaluates to true.
From the C++ standard:
6.5.1 The while statement
In the while statement the substatement is executed repeatedly until the value of the condition (6.4) becomes false. The test takes place before each execution of the substatement.
A while loop can have one of the following forms
while ( condition ) statement
while ( condition )
{
statement(s)
}
回答5:
The !
operator is a logical not
and this is how you should read it: while not valid
. You could have also written that as:
while(valid == false)
or
while(valid != true)
Note that here, again, !=
is equivalent to not equal
.
回答6:
nijansen forgot to add the most elegant one
while(!valid)
which is the same as the 2 others
来源:https://stackoverflow.com/questions/18129174/can-you-explain-how-bool-can-control-loops