C++ infinite loop - c++

I am attempting to write a loop that will repeat until the user enters one of the correct choices (either 1 or 0). For some reason when I have the loop written as below it creates an infinite loop.
I am intending for the loop to only execute while control is not 0 OR not 1, but for some reason it will always execute and becomes an infinite loop.
cout<<"Please enter 1 for another customer or 0 to quit : ";
cin>>control;
while ((control != 0 )|| (control != 1))
{
cout<<"Invalid Entry! Please enter a 1 to enter another customer or 0 to quit: ";
cin>>control;
}
I changed it to be while control less than 0 OR greater than 1, which works but I am still confused as to why the other loop is not working.

You have to use && operator.
while ((control != 0 ) && (control != 1))

(control != 0) || (control != 1)
is equivalent to,
!(control == 0 && control == 1)
but,
(control == 0 && control == 1)
is always false (there is no such number).
Therefore, the whole expression will always get true value.

The only way to break out
while ((control != 0 )|| (control != 1))
is
!(control != 0) && !(control != 1)
which is equivalent to
control == 0 && control == 1
which is impossible for all integers.

Related

Why does this while loop keep looping even when its false? In C++

This is the code in question:
int integer;
while (integer != 0 || integer != 1) {
cout << "Choose an integer: \n0\n1\n";
cin >> integer;
}
When I type 1 it continues looping even though the statement is false.
I have had this problem before or similar but it got fixed in a weird way that seems to not be working right now.
The other code that was having problems was this one:
while(chosen != 1 || chosen != 2 || chosen != 3)
{
cin >> chosen;
}
I got it fixed by doing this:
while(chosen < 1 || chosen > 3)
Does annyone know whats happening here? Ty in advance!
let me put you out of your misery
while(chosen != 1 && chosen != 2 && chosen != 3)
{
cin >> chosen;
}
This is a common issue, people translate the human idea in their heads into code: "if its not 1 or 2 or 3 then do xx". But that doesnt work.
(chosen != 1 || chosen != 2 || chosen != 3)
will always be true.
If chosen is say 0 then chosen != 1 is true. So the overall condition is true.
If chosen is 1 (which should be the end of your loop) then chosen !=1 is false, BUT chosen != 2 is true so the overall condition is still true (its true if one of the clauses is true, this is what 'or' / '||' means).
In fact there is no value for chosen which will cause the overall condition to be false. Chosen is always going to not equal one of 1 or 2 or 3.
Your problem came from the looseness of human thought, in conversation we would get what you mean, but not computers. What you wanted was "if its not 1 and its not 2 and its not 3 do xx". Ie
while(chosen != 1 && chosen != 2 && chosen != 3)

How to get out this Do-While loop?

I've this basic Arduino code, and I want to have 2 options to exit this Do-While loop.
I simplified my original code to highlight the real problem: the Do-While doesn't recognize the OR || condition to exit the loop
In this code I'm starting with two integer variables that are equal to zero and as soon as they enter the Do-While, they'will be setted equal to 2 both, so that they can immediately exit the Do-While in the first iteration.
Here's my code:
int fin = 0;
int ending = 0;
int counter = 0;
void setup() {
Serial.begin(9600);
}; //void setup
void loop () {
do {
Serial.println("We are IN Do-While #1");
ending = 2;
//fin = 2;
} while ((ending < 1) || (fin < 1)); //I have just one condition for exit the Do-While ending = 1
Serial.println("We are OUT Do-While #1");
delay(3000);
do {
counter++;
} while(counter<=100);
Serial.println("We are OUT Do-While #2");
delay(3000);
}
My problem is that I'm not setting fin = 2, because I want to test if the OR condition is working.
But it seems that it can't exit the Do-While unless they're both equal to 2. This is strange to me because the OR condition allows to exit the Do-While with a double options, in this particular case these options are:
ending<1 OR (the alternative option).. fin<1
Additionally if I change (the rest of the code is the same) the while condition with an AND it behave like I want: so that I have two ways to exit the Do-While loop.
Like this:
} while ((ending < 1) && (fin < 1));
But wouldn't be that in an AND condition I must match BOTH condition of ending >= 1 AND (at the same time) fin >= 1 to exit the loop?
Why is this happening?
and How can I solve this?
Remember that if you say while (condition), you'll loop so long as condition evaluates to true. So since your condition is
(ending < 1) || (fin < 1)
the only way for this to be false is if both ending < 1 is false AND fin < 1 is also false.
A simple trick when you're getting mixed up like this is to use DeMorgan's Law to find the contrapositive. In other words, if you want to loop while (ending < 1) || (fin < 1), that's the same as saying you want to STOP looping when the opposite is true. Using DeMorgan's Law, we can see that this is:
!((ending < 1) || (fin < 1))
!(ending < 1) && !(fin < 1)
ending >= 1 && fin >= 1
So we only STOP looping when ending >= 1 && fin >= 1!
Working the other way, if you want to STOP looping when ending >= 1 || fin >= 1, then we'll loop while the opposite is true. Again working through with DeMorgan's Law...
!(ending >= 1 || fin >= 1)
!(ending >= 1) && !(fin >= 1)
ending < 1 && fin < 1
So you wanted an AND instead of an OR all along!
But it seems that it can't exit the Do-While unless they're both equal to 2. This is strange to me because the OR condition allows to exit the Do-While with a double options, in this particular case these options are:
Actually, it's the opposite.
The loop has two options to keep going.
I'm sure you meant &&, not ||.
But wouldn't be that in an AND condition I must match BOTH condition of ending >= 1 AND (at the same time) fin >= 1?
Yes, to carry on.
Which means, you only need to not match one of them, to stop.
In your current state the loop will continue as long as (at least) one of the conditions is true (it doesnt have to be both!).
as long as ending is smaller than 2 OR fin is smaller than 2 then the loop will continue.
In your code, fin is smaller than 2 so the loop continues...
So, we are talking about the first loop in the code.
do {
Serial.println("We are IN Do-While #1");
ending = 2;
//fin = 2;
} while ((ending < 1) || (fin < 1));
Here if you don't change the "fin" variable it remains the same, and the exit condition will not be accomplished, that causing it not to end.
You could use an if condition it the loop,
do {
Serial.println("We are IN Do-While #1");
ending = 2;
//fin = 2;
if ( ending >= 1 ) break;
}
Or just use the || operator as you mentioned.

Make assignment within if-statement

I have the following problem
in my app i have severeal if-statements
if ( (number >= 1 && number <= 18) && !strcmp("half1-18", _myBetCh) ) {
}
Now I realized that I have to split this condition because I need a boolean variable after one condition
bool success = false,
if(!strcmp("half1-18", _myBetCh) {
success = true;
if (number >= 1 && number <= 18) {
}
}
Is there a workaround to this? Is it possible, for instance, to make an assignment withing the if-statement?
It's possible, like this:
if ((success = !strcmp("half1-18", _myBatCh)) && number > 1 && number < 18)
but I personally think assignments in conditions are messy and hard to read, and prefer this variation:
bool success = strcmp("half1-18", _myBetCh) == 0;
if (success && number >= 1 && number <= 18) {
// ...
}
Well, there is:
if ( !strcmp("half1-18", _myBatCh) && (success = true, number > 1 && number < 18) )
or, obviating the need for the success = false earlier
if ( (success = !strcmp("half1-18", _myBatCh)) && number > 1 && number < 18 )
Your way is easier to read though, so I would consider sticking with what you've got.

While loop condition not working

Hey basically i want both the player and the wolves to attack each other until one another are dead. But the while loop is infinite so obviously the condition is not met. But i cant see where i am going wrong with this if ( choice1 == 1) // if statement is used throughout the game to allow the user to interact through the game with choices.
while((Status.health != 0) && (Wolves.health != 0) )
{
int playerAttack = Status.strength + hitPoints() + Rock.attack;
cout<< "This is the player attack" << playerAttack;
Wolves.health = Wolves.health - playerAttack;
cout << "This is the wolves health" << Wolves.health;
if (Wolves.health <= 0)
{
cout << "\nThe wolves are dead\n ";
}
int wolfAttack = Wolves.attack + hitPoints();
Status.health - wolfAttack;
if(Status.health <= 0)
{
gameOver();
}// print out of object health.
}
Can anybody help ?
Compare:
Wolves.health = Wolves.health - playerAttack;
vs
Status.health - wolfAttack;
Notice any difference?
Well, i think the health was not exact 0 - because your condition looks only for != 0
it should be bigger than 0
while((Status.health > 0) && (Wolves.health > 0))
...
edit: also the missing = John Dibling found first
Are you sure that this is correct:
Status.health - wolfAttack;
This actually is a no-operation. Perhaps you meant:
Status.health -= wolfAttack;
in computer some of numbers cannot be represented for example 0.1, so if you calculate 1 - (0.1 * 10) its result not equal to zero. You checked only !=0 and ==0 condition. Try this:
=0 or <=0 also if your "health" variable is integer you give a error tolerance such as:
=(0.5) or <=(0.5) etc...
Most likely both values are never zero. That sounds likely, because you yourself use the <= condition.
I think your are getting negative values, I recomend to use
while((Status.health > 0) && (Wolves.health > 0) )

If statement not seeming to check other && in statement

I have an if statement that looks as follows:
int count=0;
string Check;
if ((count==4 && Check!="-s")||(count==4 && Check!="-S"))
If count equals 4 and Check equals "-s" or "-S" it still enters this if statement because of the count == 4. It totally seems to ignore the second part. Is there something I'm doing wrong?
It's always going to be the case that either Check!="-s" or Check!="-S". Hence, your if statement is equivalent to if (count==4).
Well, if Check is "-S", then it will not even check the second pair of conditions, because you check with ||. The same holds true for the opposite case. If one is false, the other is true. Replace that with a &&.
int count = 4;
string Check = "-S";
if( (count == 4 && // count is 4, alright.
Check != "-s") || // Check is "-S", alright I'm done thanks to || (OR)
(count == 4 &&
Check != "-S") )
{
// ...
}
int count = 4;
string Check = "-s";
if( (count == 4 && // count is 4, alright.
Check != "-s") || // Check is "-S", time to check the other condition pair...
(count == 4 && // count is 4, alright.
Check != "-S") ) // Check is "-s", which is different from "-S", perfect.
{
// ...
}
Now the corrected version:
int count = 4;
string Check = "-S";
if( (count == 4 && // count is 4, alright.
Check != "-s") && // Check is "-S", different from "-s", now on to the other condition!
(count == 4 && // count is 4, alright.
Check != "-S") ) // Check is "-S"... oh dang! No executed code for you.
{
// ...
}
If count == 4 and Check == "-s", then the expression to the right of the || is true. If count == 4 and Check == "-S", then the expression to the left of the || is true. So you have true or true which is true. Thus, your if-block is executed.
The right statement is:
if(count==4 && (Check != "-s" || Check!="-S"))
The statement that you wrote is true if you have count = 4 and Check = "-S" because then the first part of the OR is true.
Might be more clear to use:
if (count==4 && Check!="-s" && Check!="-S")
You should use !strcmp(Check, "-s") and !strcmp(Check, "-S") instead of !=.
If you use == you compare the pointers and that is no what you want. The pointers will always be different thus your second argument will always be true.
You want to enter the if body if and only if Check is != from either -s or -S and count is = 4 right?
if ( (Check!="-s" && Check!="-S") && count==4 )
should work.
or
if ( Check.tolower() !="-s" && count==4 )
should work.
(Do not remember the name of the function to lowercase a string, you have got to look it up)
Hope this help.