Need to add a loop to exit or repeat in C++ - c++

I want to make a code that asks user for input either to quit or repeat. I am not getting the desired output.
int main()
{
char yes,yn;
do
{
cout << "Hello world!" << endl;
while(yn != 'y' || yn != 'Y' || yn != 'n' || yn != 'N')
{
cout<<"enter (Y/N): ";
cin>>yes;
yn = yes;
}
}while(yn == 'y' || yn == 'Y');
}
Program asks for user input, when I input "Y,y,N or n", it should get out of the loop and then decide whether exit or repeat. But it isn't getting out of the loop and asking me for input again and again. I am not getting what is stopping to get out of the loop.

I didn't test, but your issue seems to be here:
while(yn != 'y' || yn != 'Y' || yn != 'n' || yn != 'N')
This condition is always true (yet shouldn't). It should be :
while(yn != 'y' && yn != 'Y' && yn != 'n' && yn != 'N')
or
while(!(yn == 'y' || yn == 'Y' || yn == 'n' || yn == 'N'))
Moreover, yn isn't initiliazed, you may want to do a do { ... } while(...); again.

while(yn != 'y' || yn != 'Y' || yn != 'n' || yn != 'N')
Is always true. It should be
while(yn != 'y' && yn != 'Y' && yn != 'n' && yn != 'N')

Firstly, this expression:
(yn != 'y' || yn != 'Y' || yn != 'n' || yn != 'N')
is always true, as yn is always not equal to one of those things.
(yn != 'y' && yn != 'Y' && yn != 'n' && yn != 'N')
is probably what you meant.
Secondly, your life would be easier if you did
yes = toupper (yes);
(i.e. put it in upper case), then you'd only have to look for one thing.
Thirdly, and most seriously, your inner while examines the value of yes before it's been initialized. Either use a do while() construct, or intialize the value to something before the loop.
Fourthly, it's not clear what you are trying do to here. Do you really need two loops at all?

I think do while loop is all you need for the execution...
int main()
{
char yes,yn;
do
{
cout << "Hello world!" << endl;
cout<<"enter (Y/N): ";
cin>>yes;
yn = yes;
if(yn=='N'||yn=='n')
{
break;
}
}while(true);
}
your loop does not exit becuse your while loop is always true..
while(yn != 'y' || yn != 'Y' || yn != 'n' || yn != 'N')
Now I have added a break statement in your loop on a if condition and changed the do while condition
in this case it will run the loop on any condition and will exit the loop only when the user enter n or N

You did not initialize variable yn. So this statement
while(yn != 'y' || yn != 'Y' || yn != 'n' || yn != 'N')
has no sense and in fact it is unnecessary.
Try the following code
#include <iostream>
int main()
{
char yes_no;
do
{
std::cout << "\nHello world!" << std::endl;
std::cout<< "Do you want to repeat? (enter Y/N): ";
std::cin >> yes_no;
} while ( yes_no == 'y' || yes_no == 'Y' );
}

Thank you all for help. I have got what i wanted from all of you. Here is the final code running successfully. I have improved my code using suggestion from everyone of yours opinion.
int main()
{
char yes,yn;
do
{
.......... (main content of program, do things here.)
do
{
cout<<"Do again? (Y/N):";
cin>>yes;
yn = toupper(yes);
if(yn!='N' && yn != 'Y')
{
cout<<"Invalid selection"<<endl;
}
if(yn=='N' || yn == 'Y')
{
break;
}
}
while(true);
}
while(yn == 'Y');
}

Related

Why is my Else If 'vehicleHeight' code being ignored? [duplicate]

This question already has answers here:
Can you use 2 or more OR conditions in an if statement? [duplicate]
(9 answers)
Closed 2 years ago.
cout << "Are you driving a vehicle onto the ferry? (y/n) ";
cin >> vehicle;
if (vehicle == 'y' || vehicle == 'Y') {
cout << "What is the length of the vehicle in feet? ";
cin >> vehicleLength;
if (vehicleLength > 20) {
extraLengthCharge = (vehicleLength - 20) * extraLengthPrice; }
cout << "Is the vehicle over 7 feet high? (y/n) ";
cin >> vehicleHeight;
if (vehicleHeight == 'y' || 'Y') {
vehiclePrice = 69.00, fuelSurcharge = 10.40;
} else if (vehicleHeight == 'n' || 'N') {
vehiclePrice = 43.00, fuelSurcharge = 4.15;
}
else if (vehicle == 'n' || vehicle == 'N') {
vehiclePrice = 0, fuelSurcharge = 0; }
}
My code will give me the correct 'fare' if the response is yes, but if I type in no it will still assign the 'yes' value. I assume it has something to do with my else if statement format for vehicleHeight.
Thanks and sorry for the novice question.
The conditions vehicleHeight == 'y' || 'Y' and vehicleHeight == 'n' || 'N' will be always true because 'Y' and 'N' will be always true and logical OR is used with them.
You should use conditions vehicleHeight == 'y' || vehicleHeight == 'Y' and vehicleHeight == 'n' || vehicleHeight == 'N' like what you used in other if statements instead.

How can I better check whether two char variables are in some set of values?

Recently, our professor has requested that we use two char variables (day) to receive the input from the user.
The code below works fine as a check to ensure that either Mo, Tu, We, Th, Fr, Sa, Su are the only two characters which are entered together as a pair. If anything else is received as input, it'll loop and ask the user for valid input.
The input should be case-insensitive, meaning that, for example, "mO" and "tu" are acceptable. It seems like there is a lot of repetition that is happening. Is there a way to clean this up?
cout << "Please enter the day of the week did you made the long distance call (Mo Tu We Th Fr Sa Su): ";
cin >> dayOne >> dayTwo;
while ((dayOne != 'M' && dayOne != 'm' || dayTwo != 'O' && dayTwo != 'o') &&
(dayOne != 'T' && dayOne != 't' || dayTwo != 'U' && dayTwo != 'u') &&
(dayOne != 'W' && dayOne != 'w' || dayTwo != 'e' && dayTwo != 'E') &&
(dayOne != 'T' && dayOne != 't' || dayOne != 'H' && dayTwo != 'h') &&
(dayOne != 'F' && dayOne != 'f' || dayTwo != 'R' && dayTwo != 'r') &&
(dayOne != 'S' && dayOne != 's' || dayTwo != 'A' && dayTwo != 'a') &&
(dayOne != 'S' && dayOne != 's' || dayTwo != 'U' && dayTwo != 'u'))
{
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cout << endl << "You have entered an invalid day. Please re-enter a day in the correct format (Mo Tu We Th Fr Sa Su): ";
cin >> dayOne >> dayTwo;
}
You could write a fold-expression that compares 2 characters to a string:
template<typename ...Days>
bool any_of(char a, char b, Days ...days)
{
return (... || (a == days[0] && b == days[1]));
}
and then use it like this:
while (! any_of(std::tolower(dayOne), std::tolower(dayTwo), "mo", "tu", "we", "th", "fr", "sa", "su"))
// keep asking for input
Here's a demo.
This should satisfy the requirement of using 2 char inputs.
You typically use tolower or toupper to convert your char variable to the correct case first. I like using tolower - it looks marginally better.
dayOne = tolower(dayOne);
dayTwo = tolower(dayTwo);
while (
(dayOne != 'm' || dayTwo != 'o') &&
(dayOne != 't' || dayTwo != 'u') &&
(dayOne != 'w' || dayTwo != 'e') &&
(dayOne != 't' || dayTwo != 'h') &&
(dayOne != 'f' || dayTwo != 'r') &&
(dayOne != 's' || dayTwo != 'a') &&
(dayOne != 's' || dayTwo != 'u'))
{
...
}
You can further change it by using memcmp to compare both characters at once, but I am not sure it would simplify the code.
Another approach that might be worth mention is to organize your data, so that you can use std functions against it (std::find)
// Example program
#include <algorithm>
#include <string>
#include <vector>
#include <iostream>
int main()
{
const std::vector<std::string> days = {
"mo", "tu", "we", "th", "fr", "sa", "su"
};
bool found = false;
while (found == false) {
char dayOne, dayTwo;
std::cout << "Please enter the first letter of the day" << std::endl;
std::cin >> dayOne;
std::cout << "Please enter the second letter of the day" << std::endl;
std::cin >> dayTwo;
std::string fullDay;
fullDay += std::tolower(dayOne);
fullDay += std::tolower(dayTwo);
found = std::find(days.begin(), days.end(), fullDay) != days.end();
std::cout << (found ? "correct day " : "invalid day, please try again ")
<< fullDay
<< std::endl;
}
}
run it here
How about
switch (256 * tolower(dayOne) + tolower(dayTwo))
{
case 256 * 'm' + 'o':
// Monday
case 256 * 't' + 'u':
// Tuesday
}
and so on?
Don't know if you're using/allowed regexes, but I'd solve it like this:
bool isDayOfTheWeek(char a, char b)
{
std::string day({a, b});
std::regex pattern("Mo|Tu|We|Th|Fr|Sa|Su", std::regex_constants::icase);
return std::regex_search(day, pattern);
}
Then simply:
cout << "Please enter the day of the week did you made the long distance call (Mo Tu We Th Fr Sa Su): ";
cin >> dayOne >> dayTwo;
while (!isDayOfTheWeek(dayOne, dayTwo))
{
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cout << endl << "You have entered an invalid day. Please re-enter a day in the correct format (Mo Tu We Th Fr Sa Su): ";
cin >> dayOne >> dayTwo;
}
I would first convert inputs to lowercase, which cuts on the amount of possible combinations. Then I would solve it with a single if-statement per day:
// returns 0-6 for valid days, -1 for invalid ones
int dayOfWeek(char a, char b) {
a = tolower(a); // requires #include <cctype>
b = tolower(b);
if (a == 'm' && b == 'o') return 0;
// 5 more here
if (a == 's' && b == 'u') return 6;
return -1; // date was invalid
}
And then I would use it as #PaulEvans suggested:
cout << "Please enter the day of the week did you made the long distance call (Mo Tu We Th Fr Sa Su): ";
cin >> dayOne >> dayTwo;
int day = -1;
while ((day = dayOfWeek(dayOne, dayTwo)) == -1)
{
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cout << endl << "You have entered an invalid day. Please re-enter a day in the correct format (Mo Tu We Th Fr Sa Su): ";
cin >> dayOne >> dayTwo;
}
// day is 0 for monday, ... 6 for sunday

Do-while Loop Conditional Statement Negation Equivalence

New to the community and programming. I was curious as to why these two logical statements are equivalent in my program. I can't seem to wrap my head around this specific logic at the moment, and I wanted to understand why it works this way.
Initially, I had written the following:
char c;
do {
cin >> c;
cout << "You entered: " << c << "\n";
} while (c != 'Y' || c != 'y' || c != 'N' || c || 'n');
return 0;
}
However, this does not seem to work unless I use &&.
Later, I found out that using or does work, but my negation must be on the outside. These are the two conditionals that confuse me. Why are they logically equivalent?
while (!(c == 'Y' || c == 'y' || c == 'N' || c || 'n')); // Will run until c is the following
while (c !='Y' && c != 'y' && c != 'N' && c != 'n'); // Will also run but without being negated.
These logical expressions in the do-while loops
while (!(c == 'Y' || c == 'y' || c == 'N' || c || 'n')); // Will run until c is the following
while (c == 'Y' && c == 'y' && c == 'N' && c == 'n'); // Will also run but without being negated.
are not equivalent.
The expression
while (!(c == 'Y' || c == 'y' || c == 'N' || c || 'n'));
is equivalent to
while ( c != 'Y' && c != 'y' && c != 'N' && !c && !'n' );
if you have an expression like for example
a == b || c == d
then its negation
!( a == b || c == d )
is equivalent to
!( a == b ) && !( c == d )
and at last to
a != b && c != d
Pay attention to that this do-while loop
char c;
do {
cin >> c;
cout << "You entered: " << c << "\n";
} while (c != 'Y' || c != 'y' || c != 'N' || c || 'n');
does not make sense. For example if the user entered 'N' nevertheless the loop continues its iteration because the first subexpression c != 'Y' evalautes to true.

Chars in do while loop conditions

I am having trouble with the last do while loop in my code. I have conditions set to stop the look when Y, N, y, or n are entered but even if those values are entered the loops continues to run and continue to ask for a Y or N. In debugging it seems that the Ascii value for the character is also stored in the variable? What do I need to change to have the do while loop end when there is an input of any of those 4 characters?
#include <string>
#include <iostream>
#include <iomanip>``
using namespace std;
int main()
{
int numberOfShapes, i, j, k, rectangleBase, rectangleHeight;
char star = '*';
char filled;
do
{
cout << "Enter the integer between 6 and 20 that you would like to be the base of the rectangle: ";
cin >> rectangleBase;
}while (rectangleBase < 6 || rectangleBase > 20);
rectangleHeight = rectangleBase / 2;
do
{
cout << "Enter the number of shapes you would like to draw(Greater than 0 and less than or equal to 10: ";
cin >> numberOfShapes;
} while (numberOfShapes <= 0 || numberOfShapes > 10);
do
{
cout << "Would you like a filled shape? [Y or N]: ";
cin >> filled;
} while (filled != 'Y' || filled != 'N' || filled != 'y' || filled != 'n');
Your loop end condition is wrong:
while (filled != 'Y' || filled != 'N' || filled != 'y' || filled != 'n');
consider that the value is 'y' then your condition will be:
(true || true || false || true)
which evaluates to true.
Change to:
while (filled != 'Y' && filled != 'N' && filled != 'y' && filled != 'n');
Then it will be:
-> 'y' (true && true && false && true) -> false
-> 'l' (true && true && true && true) -> true
You need to use && not ||:
} while (filled != 'Y' && filled != 'N' && filled != 'y' && filled != 'n');
If you write it as you say it, perhaps it would be more clear and will help to avoid these mistakes:
do
{
cout << "Would you like a filled shape? [Y or N]: ";
cin >> filled;
if (filled == 'Y' || filled == 'N' || filled == 'y' || filled == 'n')
break;
}
while (true);

Evaluating if statement with single char C++

I am trying to evaluate a single char:
bool repeat = true;
while (repeat)
//code
char x;
cout << "Would you like to tansfer another file? Y/N ";
cin >> x;
if (x == 'y' || x == 'Y')
repeat = true;
if (x == 'n' || x == 'N')
repeat = false;
else
throw "Input error";
I keep getting Input Error as my console output. Any ideas why? I can't get the while loop to repeat.
You are missing an else here:
if (x == 'n' || x == 'N')
should be:
else if (x == 'n' || x == 'N')
and you need to add braces after the while to encompass the input and if statements.
You forget braces {} after while:
while (repeat)
{
char x;
cout << "Would you like to tansfer another file? Y/N ";
cin >> x;
if (x == 'y' || x == 'Y')
repeat = true;
else
if (x == 'n' || x == 'N')
repeat = false;
else
throw "Input error";
}