Bool variable. Logic of the check - c++

So I have a question about bool variables.
This is a program which checks whether the due is payed on time and if it is not, it is multiplied by 1.10.
#include <iostream>
using namespace std;
int main()
{
float Dues;
cout<<"Enter ammount: \n";
cin>>Dues;
cout<<"On time? (y/n)";
char yn;
cin>>yn;
bool Overdue = yn !="y"; //TRUE (1) if it is late, FALSE (0) if it is on time
float AmountDue;
AmountDue = Overdue ? Dues*1.10 : Dues;
cout<<"Ammount due: ";
cout<<<<AmountDue;
return 0;
}
I don't undestand the logic of the bool
We have
bool Overdue = yn !="y";
Now this is my understaning of the logic of the bool and it is NOT right
If "n" is entered => N is NOT Y which is CORRECT therefore the bool is true => 1
If "y" is entered => Y is NOT Y which is WRONG, therefore fasle => 0
But it is actually the other way around and I can't explain it logically to myself.
On what logic is based bool Overdue = yn !="y"; ?

In addition to jrok's answer the problem you are encountering is that you assume that lowercase and uppercase characters are the same thing. They are NOT. 'y' and 'Y' are two different characters. Same thing for 'n' and 'N'.
You write:
If "n" is entered => N is NOT Y which is CORRECT therefore the bool is
true => 1
No. 'n' is not 'y'.
If "y" is entered => Y is NOT Y which is WRONG, therefore fasle => 0
It's CORRECT. 'y' is NOT 'Y'.
Try this instead:
bool Overdue = (yn != 'n') && (yn != 'N');

The reason for unexpected behaviour is that you're comparing a char with a string literal "y". String literals are of type const char[n] where n is the length of the literal including the terminating NUL character.
Compare with a character literal instead:
yn != 'y'
When you say this: yn != "y", the char gets promoted to int and the string literal decays to const char*. How is this supposed to behave is unspecified by the standard.
The result of the expression gets stored in bool Overdue. When yn holds 'n', the expression is true ('n' is indeed different than 'y') so true will be stored, and vice versa).

Related

How do I get multiple conditions within one while loop?

I am using a while loop and I want to user to input r, R, p, or P. But when I add more than one condition like:
while ((userInput != "r") || (userInput != "p" || (userInput != "R") || (userInput!= "P")) {
cout << "Please enter a valid option" << endl;
cin >> userInput;
}
my program will forever be stuck in the loop. Where as if I input it like this:
while (userInput != "r") {
cout << "Please enter a valid option" << endl;
cin >> userInput;
}
Then my code will exit the for loop if user inputs "r"
So why does the first block of code not work? I have no errors, which means it has to be a logical error but I do not understand. How can I get more thano ne condition in a for loop and make it work?
You need to use && instead of || because using || the condition in the while is always true. When you write “r”, for example, the condition userinput != r is false but the rest are true, with && all the expressions turn to false and the while ends.
Why does the above condition not work?
The reason is because if you say x is not 3 or x is not 5, then if x is 3, then x is not 5, so the entire statement evaluates to true. Your different userInput != 'r' and userInput != 'p' are just like that situation with the x.
To show it simpler, I'll show a truth table for or. When the expression evaluates to true, your while loop would continue below those circumstances, where p and q are statements that may be true or false like userInput != 'r'.
|| -- or
q\p|_T_|_F_|
_T_|_T_|_T_|
_F_|_T_|_F_|
Meaning that with an or clause, the only way it's false is if all parts are false.
An And clause appears to be what you want. It's truth table is:
&& -- and
q\p|_T_|_F_|
_T_|_T_|_F_|
_F_|_F_|_F_|
Meaning, that with an and clause, the only way for it to be true is if all clauses are true.
So if you want the response to be neither r nor p nor R nor P, etc, use && for and:
while ((userInput != "r") && (userInput != "p") && (userInput != "R") && (userInput!= "P")) {
And then the while loop will exit as soon as userInput does not match any of r, p, R or P. This is because as the program evaluates, it checks:
With the example of userInput as "g":
Does the userInput g equal r? No. So the first clause is True. Does the userInput g equal p? No. So the second clause is True. Does the userInput g equal R? No. So the third clause is True. Does the userInput g equal P? No. So the fourth clause is True. Since all four are true, then the whole statement is true, and the while loop continues.
With the example of userInput as "R":
Does the userInput g equal R? No. So the first clause is True. Does the userInput g equal R? No. So the second clause is True. Does the userInput g equal R? YES. So the third clause is False. Since a part of the statement is false, the whole and clause is false, so the while loop exits.

How to do input validation simply in C++?

I want to give an error message if the input is neither character c nor h but I can't get it to work! I looked up some other answers but they mostly use throw/catch method which I didn't understand at all. I just started programming and error handling is in Chapter 20 or 21. Help me out with the most simple way as possible.
This is what I've tried:
cout << "Enter 'c'(even) or 'h'(odd): ";
cin >> your_guess;
if((your_guess != ('c' || 'h')) == false) {
cout << "Wrong Input. Game is restarting... " << endl;
// restart the game ...
}
But it always says Wrong Input. ....
(your_guess != ('c' || 'h')) == false
is wrong. ('c' || 'h') simply evaluates to true. The built-in operator|| takes two bool arguments:
bool operator||(bool, bool)
And since 'c' and 'h' are both not NUL characters, they convert to true.true OR true is true. The language doesn't create some magical entity with which you can do operator==/operator!= with char to see if the character is among those you've listed.
Then, later the bool and char are promoted to int to do the inequality check. I'd guess your_guess won't be equal to 1. And I don't mean '1' (ASCII 49), but 1 (ASCII 1). So you've effectively written if(true)...
What you meant to say is:
(your_guess != 'c' || your_guess != 'h') == false
or
!(your_guess != 'c' || your_guess != 'h')
or
your_guess == 'c' && your_guess == 'h' // your_guess equal 'c' and 'h' at once?
and now you see that there's something wrong with the logic.
The right code for the condition is one of these:
your_guess != 'c' && your_guess != 'h'
!(your_guess == 'c' || your_guess == 'h')
It's just De Morgan's laws all around.
How to do input validation simply in C++?
If the above is not simple for you, you can use switch (because you're probably going to use it anyway). But each case tests variable against compile-time constant.
If the letters you want to check for are stored in a variable, I suggest this:
std::string valid_characters = "ch"; // this will be our "magical entity"
if(valid_characters.find(your_guess) == std::string::npos)
{
// you have entered a character that is not 'c' nor 'h'
}
You can try
switch(your_guess){
case 'c' :
case 'h' :
// do something
break;
default :
cout<<"invalid Input"<<endl;
break;
}
If you are doing an error message in c++, using cerr instead of cout might be something you may want to think about doing in addition to the changing:
your_guess!=('c'||'h'))==false
To one of the correct forms listed in the other answers

c++ need help to understand

So I have this piece of code.
I understand all the things beside the fact that when does the loop actually take place again. I mean what is meant by the e(!valid) statement. Does it refer to its numeric value or what? Can somebody please explain this to me. Consider all required variable declared. And ignore uppercase.
The code is:
do
{
valid=1;
gotoxy(22,7);
gets(emailid);
int flag=0;
for (int i = 0; emailid[i] != '\0'; i++)
if (emailid[i] == '#')
flag++;
If(!flag)
{
valid = 0;
cout << "not a valid id. Try again";
getch();
}
} while(!valid);
So mainly I want to know that it is working, with emphasis on what does !valid and !fail mean.
From what I could get, it has to do with its numeric values but I am still confused.
To answer the question:
} while (!valid);
means: treat the integer behind valid as a boolean. (assuming it is an integer, as it was given a value of 1)
i == 0 -> false
i != 0 -> true
!valid:
valid == 0 -> true
valid != 0 -> false
In C++ the value 0 is considered "false" and any other integer is considered "true". In this case while valid is equal to 0 the loop runs.
Numeric value can be promoted to bool type this way:
Zero means false and other values mean true. So !valid will return true only if valid == 0.
What it means is your do while() loop will repeat itself until valid equals value other than 0.

Incorrect string comparison

I have a problem i cannot figure out at all!
in my program the user enters numbers to be sorted. i had to be able to sort infinity, negative infinity and the so called "Nullity" (these i defined early in the program)
if the user wants to enter infinity for example they have to enter "Pinf" into the string.
my issue is i store the users input in a std::string and then check if the string is "pinf" or "Pinf" even tho i have entered the number 3 so the string is "3", it still goes into the if statement, what have i done wrong?!
My code is below;
string Temp;
cin>> Temp;
if (Temp.find("Pinf")||Temp.find("pinf")) {
Num = Pinfinity;
}
It thinks the if statement is true everytime.
1.Error - you are using | instead of ||.
2.Error - findreturns
The position of the first character of the first match. If no matches
were found, the function returns string::npos.
You should change
if (Temp.find("Pinf")|Temp.find("pinf")) {
to
if ((Temp.find("Pinf") != string::npos) || (Temp.find("pinf") != string::npos)) {
If you are just searching for Pinf or pinf then you can use this. Note the logical or operator is ||.
if (Temp == "Pinf" || Temp == "pinf") {
| is a bitwise or operator. Use || in place of |
if ( Temp.find("Pinf") != npos || Temp.find("pinf") != npos )

what is the difference in using && and || in the do...while loop?

#include<iostream>
using namespace std;
int main()
{
char again;
do
{
cout<<"you are in the while loop";
cout<<"do you want to continue looping?";
cin>>again;
} while (again != 'n' || again != 'N');
system("pause");
return 0;
}
i know something is wrong with the test condition in the 'while'. But I can't figure it out.
when the input of the user is neither 'n' nor 'N', the loop should keep on printing the code "you are in the while loop". Once 'n' or 'N' is pressed, the program will be terminated.
However for my code, program will keep on looping the code regardless what character i enter.
But when i change the '||' to '&&', the program can ran as desired.
Anyone can tell me what is going on?
This is a common boolean logic question. || means "or," which means "as long as one side of this is true, then the expression is true." So when you pass an uppercase 'N' to c != 'n' || c != 'N' the program says "well, 'N' is not equal to 'n', therefore one side of the expression is true, therefore the whole expression is true and there is no need to check the rest of the expression." Even when you press lowercase 'n', the program says "well, 'n' is equal to 'n', but it's not equal to 'N', therefore one side of the expression is true, therefore the whole expression is true." This is what is happening in your while loop.
On the other hand, && means "and" which means "both sides of the expression must be true"; when you pass an uppercase 'N' to c != 'n' && c != 'N' the program thinks "'N' is not equal to 'n', but it is equal to 'N', therefore only one side of the expression is true, therefore the expression is false."
This gets confusing because if you were testing to see if the characters entered were equal to particular values you would use || (e.g., "I want to know if 'a' or 'b' or 'c' was entered").
Basically, when you would use || for a particular expression, and you want the opposite of that expression then you need to change to && (e.g., I want none of 'a', 'b' or 'c'; or to put it another way, the value cannot be 'a' and it cannot be 'b', and it cannot be 'c'"). Likewise, if you would use && for a particular expression, and you want the opposite of that expression then you need to use ||. This is one of De Morgan's laws, which I would recommend you read up on so you can avoid having to rediscover each of them on your own.
Yes: || is "or" and && is "and".
Every character is either "not 'n'" or "not 'N'" because it can't possibly be both 'n' and 'N' simultaneously.
Another (probably simpler to read) way of writing the condition would be:
!(again == 'n' || again == 'N')
which means "the opposite of (again is either 'n' or 'N')".
It is the boolean algebra called "De Morgan's laws".
Not (P And Q) = (Not P) Or (Not Q)
Not (P Or Q) = (Not P) And (Not Q)
In your case, you want users not to enter 'n' or 'N', it can be translate in to this logic.
!(again == 'n' || again == 'N')
When applying De Morgan's laws, it will be
(again != 'n' && again != 'N')
For more info, you might want to read Propositional logic
Although the original poster is happy now, I didn't see this in the other answers:
(true && true ) == true
(true && false) == false
(false && true ) == false
(false && false) == false
(true || true ) == true
(true || false) == true
(false || true ) == true
(false || false) == false
!true == false
!false == true
That's everything!
I understand your problem well,and here is the explanation:
The do-while loop is an exit-condition loop. This means that the body of the loop is always executed first. Then, the test condition is evaluated. If the test condition is TRUE, the program executes the body of the loop again. If the test condition is FALSE, the loop terminates and program execution continues with the statement following the while.
in your code,when you press'n' or'N',your test condition will be always one true and one false,
so when you use || you will satisfy the test condition (true||false=true) ,so the program will execute the body of the loop again.
but when you use && ,this will gives (true && false =false),the test condition is not statisfied anymore,so the program will not execute the body of the loop again.
I hope that's helpful.....enjoy programing!
Ameraradi
&& is a logical AND.
|| is a logical OR.
(also, & is a bitwise AND, and | is a bitwise OR.)
you might want to try while(!(again == 'n' || again == 'N'))