do
{
cout << "Car is coming ... " << "[P]ay or [N]ot?" << endl;
ch=getch();
} while ( ch !='q' || ch != 'Q');
Why will the code on top not work while the code below does? I tried it with parenthesis around each statement in numerous ways and the compiler would pop an error every time until I regrouped them as I did below. I'm just wondering why it does this.
do
{
cout << "Car is coming ... " << "[P]ay or [N]ot?" << endl;
ch=getch();
} while ( !(ch=='q' || ch=='Q') );
I'm using Visual Studio 2008 as my compiler; x86 architecture.
Learn De Morgan's laws
(not A) or (not B)
is not the same as
not (A or B).
(ch != 'q' || ch != 'Q') is always true: "ch is not equal to 'q' or ch is not equal to 'Q'".
The problem is your boolean logic is off and the two while conditions are not the same.
Top: Character is not 'q' or is not 'Q'
Bottom: Character is not ('q' or 'Q')
The Top will return true for every single character possible. The bottom will return true for every character except 'q' and 'Q'
I think you want this in your first example:
ch !='q' && ch != 'Q'
You want that the input is not q AND not Q.
!(ch=='q' || ch=='Q') is equivalent to ch!='q' && ch!='Q'. See also De Morgan's laws.
You've got the logic backwards, that's my negating it works. By DeMirgan's laws, !(ch == 'Q' || ch == 'q') is the same as ch != 'Q' && ch != 'q'.
Since a if it cannot be both little q and big Q at the same time, while (ch != 'Q' || ch != 'q') doesn't make sense because if it is 'Q' then it won't be 'q', and vice versa.
When inverting all your logic using '!', you did right by reversing the conditional operators "==" to "!=", but you forgot to reverse the logical operators "||" to "&&". Thus, this should be correct:
while (ch!='q' && ch!='Q');
I use C#, so while code above will work, I would have used this instead as it is easier to read:
while (ch.ToUpper() != 'Q');
Related
one would think this is easy, but for some odd reason, my conditional statement is ignoring user input.
If I input a character 'N' or 'n' it still executes the 'Y' portion of the conditional statement, have a look:
while (i < 10) {
cout << "Would you like "<< nameOfDish[i] << "? Please enter Y or N.\n";
cin >> userResponse;
if (userResponse == 'y' || 'Y')
{
cout << "How many orders of " << nameOfDish[i] << " would you like?\n";
cin >> quantityOfDish[i];
if (quantityOfDish[i] == 0) {
cout << "I suppose you're entitled to change your mind.\n";
}
else if (quantityOfDish[i] < 0) {
cout << "Your generosity is appreciated but I must decline!\n";
quantityOfDish[i] = 0;
}
i++;
}
else if (userResponse == 'n' || 'N')
{
i++;
}
else
{
cout << "I think you mumbled NO, so I'll just go on.\n";
i++;
}
}
Is there any particular reason why despite inputting 'n' it still goes into the 'Y' if conditional block?
I have stepped through the code in the debugger, and I noticed that the userResponse variable is being read in properly. Yet, the if condition does not seem to be working properly. Thanks!
This statement (and your other if statement) is not doing what you think it does:
if (userResponse == 'n' || 'N')
Try this instead:
if (userResponse == 'n' || userResponse =='N')
You need to define each logical operation individually in a condition check. You will have to compare userResponse with n and N separately.
if (userResponse == 'y' || userResponse == 'Y')
{
cout << "How many orders of " << nameOfDish[i] << " would you like?\n";
cin >> quantityOfDish[i];
if (quantityOfDish[i] == 0) {
cout << "I suppose you're entitled to change your mind.\n";
}
else if (quantityOfDish[i] < 0) {
cout << "Your generosity is appreciated but I must decline!\n";
quantityOfDish[i] = 0;
}
i++;
}
It's been awhile since I worked in C++, but I'm fairly sure I know what's going on.
The || operator does not work on a single conditional, there must be two complete conditionals, one on each side. Try replacing your if statement with this line:
if (userResponse == 'y' || userResponse == 'Y')
Maybe you are used to SQL? You need to repeat the userResponse
if userResponse == 'n' || userResponse == 'N'
Otherwise you are actually testing
if userResponse is 'n' or the char'N' exists
The error in this code is, as others have pointed out, the if statement. However, I feel this may need some clarification. Every C++ expression returns a value. For example.
userResponse == 'y'
returns the value 1 if userResponse is 'y' and 0 if it is anything else. The operator || returns 1 if either the left or the right expression is non-zero.
Finally, the if statement checks to see whether or not the expression is zero or non-zero. So,
if (5)
cout << "X";
else
cout << "Y";
will print X and
if (0)
cout << "A";
else
cout << "B";
will print B.
Now, we can begin to understand why your code compiled successfully, but didn't do what you wanted it to.
if (userResponse == 'y' || 'Y')
In this example, the || operator will always return 1 because the expression on the right, 'Y', will always be non-zero (specifically, it will be 89, since C++ characters are just aliases for their ASCII corresponding number). And of course,
if (userResponse == 'y' || userResponse == 'Y')
work as intended. But there is a much better solution and that would be the switch statement, whose purpose is to handle situations like this. Here it is in action:
switch (userResponse) {
case 'y':
case 'Y':
//The user answered yes, handle that situation here.
break;
case 'n':
case 'N':
//The user answered no, handle that situation here.
break;
default:
// The user did not enter a valid answer,
// handle that situation here.
break;
}
do {
cout << "Enter the account type (C for current and S for savings): ";
cin >> account_type;
} while (account_type != 'S' || 'C');
I have account_type set as char,the problem is that everytime i run the program and i input S or C the loop keeps repeating.Can anyone help me know why its happening?
All non-zero values in c++ evaluate to true when used in a boolean operation. So account_type != 'S' || 'C' is the same as account_type != 'S' || true. Which means your loop never exits.
What you need to do is to preform both checks
do {
cout << "Enter the account type (C for current and S for savings): ";
cin >> account_type;
} while (account_type != 'S' && account_type != 'C');
Its because you cant say 'S' || 'C', you would think c++ would think that you mean if account_type is S or C however c++ looks at this in 2 separate sections: (account_type == 'S') || ('C'). ('C') will default to true therefore the loop loops forever.
What you need to write is:
do {
cout << "Enter the account type (C for current and S for savings): ";
cin >> account_type;
} while (account_type != 'S' && account_type != 'C');
You need to change the || to && because if account_type is S then it cant be C and the same vice versa therefore the loop never finishes.
Your while check is wrong. You have to write it like this:
while (account_type != 'S' || account_type != 'C')
You can't perform || checks, or any for that matter like that, you must always re-state the variable.
So I am supposed to convert English words to Pig Latin using stringConvertToPigLatin(string word) function. All the answers I could find on the internet were using char[], and I am not allowed to do so.
The program is supposed to begin with adding -way if the first letter is a vowel, and adding -ay if it's a consonant. The problem is that it is always adding "-way", even if my "word" has no vowel at all. What am I doing wrong? This is my function:
string ConvertToPigLatin(string word)
{
char first = word.at(0);
cout << first << endl;
if (first == 'a' || 'A' || 'e' || 'E' || 'i' || 'I' || 'o' || 'O' || 'u' || 'U')
{
word.append("-way");
}
else
{
word.append("-ay");
}
return word;
}
As noted in the comments your if statement is wrong. Each comparison needs to be done individually. From the comment.
if (first == 'a' || first == 'A' || first == 'e' || ...)
However, rather than using a long if statement you should consider stuffing all of the vowels into a string and using find. Something like the code below will be easier to read and follow.
#include <iostream>
#include <string>
std::string ConvertToPigLatin(std::string word)
{
static const std::string vowels("aAeEiIoOuU");
char first = word.at(0);
std::cout << first << std::endl;
if (vowels.find(first) != std::string::npos)
{
word.append("-way");
}
else
{
word.append("-ay");
}
return word;
}
int main()
{
std::cout << ConvertToPigLatin("pig") << '\n';
std::cout << ConvertToPigLatin("alone") << '\n';
}
This outputs
p
pig-ay
a
alone-way
I'll explain why your code isn't working:
if (first == 'a' || 'A' || 'e' || 'E' || 'i' || 'I' || 'o' || 'O' || 'u' || 'U')
Let's walk through that iff statement using the word "Pig"
First the program checks first == 'a'... first == 'P' so that is false.
Then the program checks to see if false || 'A' is true. Since 'A' is true, false || 'A' is also true.
Short circuit evaluation kicks in, and the code doesn't bother checking the rest of the statement, the if condition is true so -way is appended.
To do what you want, you need to compare first to each letter. I.E.,
if (first == 'a' || first == 'A' || ...
Don't worry too much, this is a pretty standard mistake.
I'm just stuck on some logic statements.
specifically the ones that are in the function char GetInteger() so how would I only allow 3 values to cause the loop to exit.
char GetInteger( /* out */ char& usrinput)
{
do
{
cin >> usrinput;
cin.ignore(200,'\n');
if (usrinput != 0 || usrinput != 1 || usrinput != 2)
{
cout << "Invalid Input." << userinput << " Try Again\n";
}
} while(usrinput != 0 || usrinput != 1 || usrinput != 2);
return userInput;
}
Two issues with this code:
First userinput has a type of char. So when you read from a stream you read a single character (after dropping white space). So when a user types 1<enter> you get the character '1' in the variable userinput. Note the character '1' is not the same as the number 1.
Thus your test should be:
userinput != '1';
Secondly your boolean logic is wrong. When first learning it is sometimes easier to state the problem as a list of values that you would like to be acceptable (not the unacceptable ones).
You want the conditions to be false if the userInput has one of your accepted values (any good value will fail the test and thus not invoke the bad code). The first step to this is to get a true if any of your values are valid.
// If any value is good then true.
userinput == '1' || userinput == '2' || userinput == '3'
To invert this just add a not to the expression.
if (! (userinput == '1' || userinput == '2' || userinput == '3') )
Note: in boolean logic
!(A || B) => (!A && !B)
So you could re-write the above as:
if (userinput != '1' && userinput != '2' && userinput != '3')
I think this was your main mistake you converted the == into != but did not convert the || into &&.
I would also suggest that you could simplify this (as you may get more valid result) byconverting this into a range based test.
if (userinput < '1' || userinput > '3')
{
// Test Failed.
}
Additionally. Since you have the test in two places. You should yank it outinto its own function. Then you can call the function to do the test.
bool isUserInputValid(char userInput)
{
return userInput >= '1' && userInput <= '3';
}
Now we can re-write your original function as:
char GetInteger( /* out */ char& usrinput)
{
do
{
cin >> usrinput;
cin.ignore(200,'\n');
if (!isUserInputValid(userinput))
{
cout << "Invalid Input." << userinput << " Try Again\n";
}
} while(!isUserInputValid(userinput));
return userInput;
}
First of all, you should use int instead of string as you are reading integer.
You can use while(1) instead of putting condition in while. Inside while loop, if your selection is 0 or 1 or 2, you can simply break the loop.
I must have missed something. I'm doing an exercise to learn c++ and it asks that if a user inputs either c,p,t or g character then carry on, otherwise re-request prompt, so I wrote this:
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
int main(void){
cout << "Please enter one of the following choices:" << endl;
cout << "c) carnivore\t\t\tp) pianist\n";
cout << "t) tree\t\t\t\tg) game\n";
char ch;
do{
cout << "Please enter a c, p, t, or g: ";
cin >> ch;
cout << "\"" << ch << "\"" << endl;
}while(ch != 'c' || ch != 'p' || ch != 't' || ch != 'g');
cout << "End" << endl;
cin.clear();
cin.ignore();
cin.get();
return 0;
}
This does not work and all I get is the prompt re-requesting it even when pressing either of the correct characters.
However if I change this line:
while(ch != 'c' || ch != 'p' || ch != 't' || ch != 'g');
to
while(ch != 'c' && ch != 'p' && ch != 't' && ch != 'g');
why is that? My understanding is that the "OR" statement should work as one of the tests is correct.
why is that? My understanding is that the "OR" statement should work as one of the tests is correct.
Exactly. There is always one of the tests that passes. A character will either be not 'c', or not 'p'. It can't be both 'c' and 'p'. So the condition is always true, leading to an infinite loop.
The alternative condition with the conjunctions works because it is false as soon as ch is equal to one of the alternatives: one of the inequalities is false, and thus the whole condition is false.
My understanding is that the "OR" statement should work as one of the tests is correct.
Well, you could use ||, but the expression would have to be:
while(!(ch == 'c' || ch == 'p' || ch == 't' || ch == 'g'));
By applying the De Morgan's law, the above simplifies to:
while(ch != 'c' && ch != 'p' && ch != 't' && ch != 'g');