How to (not) rerun c++ code? - c++

I am doing the basic console c++ "do u want to rerun program?" dance,
and failing. This is what I'm using
int main()
{
char repeat = 'y';
while (rep == 'y' || 'Y')
{
{
//primary code is here
}
cout << "\n\tRerun program? y/n";
cin >> repeat;
if (rep == 'n' || 'N')
{cout << "\n\tExiting program\n";}
}
return 0;
}
When my program finishes, it restarts and outputs "Exiting program"
no matter what I input at "Rerun program?"I understand this has
something to do with flushing or resetting the char "repeat"?
No idea how to do that and google isn't helping.
I can submit the primary program code on request, but I doubt it has
anything to do with this error.

if (rep == 'n' || 'N') will be always true,
because it actually doing if( (rep =='n') or 'N') ('N' has nonzero value which mean the if-statement is doing : if( (rep =='n') or true) ), so you always got "Exiting program" printed.
you should you if (rep == 'n' || rep =='N')
and the same, your while statement should be while (rep == 'y' || rep == 'Y')
OR
move the
cout << "\n\tExiting program\n";
out your while loop without condition to get it printed only when finish the loop

Related

Input not being read properly by if condition statement

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;
}

How to use the or statement (||) correctly, in an else-if statement

Consider this code:
string GameExit;
bool GameChoiceGo = true;
while (GameChoiceGo == true)
{
system("cls");
cout << "\n Are you sure you want to exit? (Yes or No) ";
cin >> GameExit;
if (GameExit == "y" || "Y" || "yes" || "Yes" || "YES")
{
cout << "User typed Yes";
Sleep(3000);
system("cls");
break;
}
if (GameExit == "n" || "N" || "no" || "No" || "NO")
{
cout << "User typed No";
Sleep(3000);
system("cls");
GameChoiceGo = false;
}
else
{
cout << "\nI'm sorry but, " << GameExit << " is not a acceptable choice. Type: Yes or No.\n\n\n";
Sleep(3000);
system("cls");
}
}
break;
Here, only the first statement is activated. Even if the user types "No" or anything else, it will output "user typed yes".
The else-if statements work if I replace the or statements with only one statement (i.e. "y" and "n"). The only problem is, I want to have any possible version of yes and no that the user might type in the code.
Any ideas why the code is not working correctly?
I'm sorry, but you have to write GameExit == for every condition you want to check:
if (GameExit == "y" || GameExit == "Y" || GameExit == "yes" || GameExit == "Yes" || GameExit == "YES")
If you write if ("y") (which is basically what you are doing, only with more statements), the const char[] will decay to a const char*, and that pointer will be compared to 0. Now, that pointer will never be null, as there will always be memory allocated for the string literal.
A better solution is to (1) make an array with all the options, so that checking the conditions becomes a simple search or (2) convert the input to all lowercase for example, and compare that.
// 1)
std::vector<std::string> options = { "y", "Y", "yes", "Yes", "YES" };
if (std::find(options.begin(), options.end(), GameExit) != options.end());
// or
if (std::any_of(options.begin(), options.end(), [&GameExit](const auto& value) {
return GameExit == value;
});
// 2)
std::transform(GameExit.begin(), GameExit.end(), GameExit.begin(), ::tolower);
if (GameExit == "y" || GameExit == "yes");
You can look up the functions if you do not know what they do :).
Correct way using OR operator in "your" code is as below (note the explicit use of == statements between || operators):
if (GameExit == "y" || GameExit =="Y" || GameExit =="yes" || GameExit =="Yes" || GameExit =="YES")
{
cout << "User typed Yes";
Sleep(3000);
system("cls");
break;
}
if (GameExit == "n" || GameExit =="N" || GameExit =="no" || GameExit =="No" || GameExit =="NO")
{
cout << "User typed No";
Sleep(3000);
system("cls");
GameChoiceGo = false;
}
PS: The above answer is not intended to give the best programming practice in a similar situation but to give the specific answer to the OP with the minimal code change :)
// -----
EDIT: Here is a better approach using STL. Note that (unsorted) array lookup requires linear search, whereas unordered_set, which is a hash set, has (on average) constant time lookup. This will be faster especially when the yes, no etc. options are plenty.
#include <unordered_set>
...
// These sets can be as large as possible or even dynamically
// updated while the program is running. insert, remove, lookup will
// all be much faster than a simple array.
unordered_set<string> ySet{"y", "Y", "yes", "Yes", "YES"};
unordered_set<string> nSet{"n", "N", "no", "No", "NO"};
if (ySet.find(GameExit) != ySet.end())
{
cout << "User typed Yes";
Sleep(3000);
system("cls");
break;
}
if (nSet.find(GameExit) != nSet.end())
{
cout << "User typed No";
Sleep(3000);
system("cls");
GameChoiceGo = false;
}
...
You need to define a complete equality for each expression like this:
if ( gameExit == "y" || gameExit == "Y" ) {}
GameExit == "y" || "Y" || ....
is incorrect. The correct method is:
GameExit == "y" || GameExit == "Y" || ....
and so on, both for the yes or no case.

C++ Program will not exit while loop

My C++ program will not exit while loop below when the user enters either 'Q' or 'q' to quit the program. The first two options work fine and call their appropriate functions, but the 'Quit the program' option just starts the while loop over again indefinitely.
#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
int main()
{
char choice; //Varible to hold the user's choice.
while (choice != 'Q' || choice != 'q')
{
//Display the menu and retrieve the user's choice.
cout << "Please choose from one of the options below:\n\n";
cout << "A. Calculate the total amount of your bill [Enter A]\n";
cout << "B. Calculate your BMI [ENTER B]\n";
cout << "Q. Quit the program [Enter Q]\n\n";
cout << "Enter your choice: ";
cin >> choice;
//Either calculate the user's bill or their BMI based on their choice.
if (choice == 'A' || choice == 'a')
{
caLculateBillAmount();
}
else if (choice == 'B' || choice == 'b')
{
calculateBMI();
}
}
return 0;
}
You should simply use while (choice !='Q' && choice !='q') {...}. And yes, you should initialize choice to something different from 'Q' and 'q'. Just do something like char choice=0;.
Ask yourself what the following evaluates to:
choice != 'Q' || choice != 'q'
If choice is 'Q' then choice is not 'q' so the right-half of the test is true.
If choice is 'q' then choice is not 'Q' so the left-half of the test is true.
You need to use && in place of ||, or you could simply use toupper(choice) != 'Q'.

C++ equality check on char from cin against another char never equates to true??? (No compiler errors)

I'm stuck as to why the condition below isn't triggering when either an 'n' or a 'y' is entered at the console. When executed you can't get out the the if statement, but i know for sure that
!(cin >> again)
isn't the culprit, as that was previously the only condition in the if statement and I was able to skip/enter the if block if a character/numeral was entered, which was as expected. Here is the code:
char again;
while (1) {
cout << endl;
cout << "I see another one, care to shoot again? (y/n): ";
if (!(cin >> again) || (again != 'n') || (again != 'y')) {
// Error checking for numberals & non 'y' or 'n' characters
cout << "Please enter 'y' or 'n' only." << endl;
cin.clear();
cin.ignore(1000, '\n');
continue;
}
break;
}
I'm stumped on this so any help would be hugely appreciated!
if(...|| (again != 'n') || (again != 'y')) {
is faulty logic. What you say is
if "again" is not n or it's not y, then do the following...
now, since "again" can't be n and y at the same time, this always evaluates to true; most probably, even your compiler notices that and just jumps right into your if's content.
What you want is something like
if(!(cin>>again) || ( again != 'n' && again != 'y') {
Because that reads
if cin>>again didn't work or again is neither n nor y then,...

Confusion with the OR logical Operator in a Loop

A bit earlier on an IRC channel, someone asked a question about his code - essentially, his program was running on an infinite loop:
#include <iostream>
using namespace std;
int main()
{
cout << "This program adds one to your input." << endl;
char choice = 'n';
int num = 0;
while (choice != 'y' || choice != 'Y')
{
cout << "Enter number: ";
cin >> num;
num++;
cout << "Your number plus 1 is: " << num << endl;
cout << endl << "Continue/Quit? Type 'Y' to quit, any other key to continue: ";
cin >> choice;
}
cout << "By choosing 'Y', you exit the loop." << endl;
return 0;
}
Paying attention to the loop header, it seems that the loop should be working perfectly fine, but whenever it comes time for me to enter Y or y in order to exit, the loop keeps running. Considering that the while loop won't evaluate the expression to the right if the one on the left is true, this makes it especially confusing. But in any case, even if I input Y or y the loop keeps running! I'd like a somewhat in-depth explanation of why this happens, I've been trying to reason it out, look back in my textbook etc. but I can't seem to understand why... I've changed the OR into an AND, but what makes OR so bad and causes it to malfunction?
Thanks all.
Condition (choice != 'y' || choice != 'Y') is always true, so loop will run indefinetely.
If choice == 'y', then you get (false || true) == true;
if choice == 'Y', then you get (true || false) == true.
You need to use while(choice != 'y' && choice != 'Y') instead, in this case you exit loop only if you get 'y' or 'Y', otherwise you get (true && true) and continue.
The OR operator between many statements returns true if at least 1 of the statements is true, no matter if the others are false or true. In your case, choice != 'y' || choice != 'Y' will be evaluated like this:
First statement is true: Execute while loop.
First statement is false: Check if the second statement is true.
Second statement is true: Execute while loop.
Second statement is false: don't execute while loop.
Specifically, when the compiler arrives at choice != 'y', if choice == 'Y', then it will still execute, because choice != 'y' is true, in fact choice is equals to Y, so it's different from y.
If, on the other hand, choice is equals to y, then it will check if the second statement is true, but we know that choice is equals to y, so choice is different from Y, and so on...
You make a mistake,you should change "||" to "&&"