Yes/No program using while loop in C++ [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I'm trying to make a program that asks the user whether they would like to continue to the next calculation. For some reasons whenever I enter y or Y, the program ends. However, if I use only one condition inside the if statement(without '||'sign), the code works fine. I just want to make sure that the user can enter both upper and lower case.
What's wrong with the code? Is there a better way to do this?
int main()
{
char choice;
while(true)
{
cout<<"Would you like to perform other calculation?(Y/N)"<<endl;
cin >> choice;
if(choice == 'Y'|| choice =='y'){
return true;
}else if(choice =='N'||choice =='n'){
return false;
}
}
return 0;
}

The return statement ends a function, in this case, this is the main, so it ends your program, whatever value you're returning.
If you only want to get out of your loop you have two solutions:
Use a boolean:
int main()
{
char choice;
bool run = true; //#stefaanv
while(run)
{
// Make your calculation
cout<<"Would you like to perform other calculation?(Y/N)"<<endl;
cin >> choice;
if(choice =='N'||choice =='n'){
run = false;
}
}
return 0;
}
Use break to exit your loop:
int main()
{
char choice;
while(true)
{
// Make your calculation
cout<<"Would you like to perform other calculation?(Y/N)"<<endl;
cin >> choice;
if(choice =='N'||choice =='n'){
break;
}
}
return 0;
}
But both these solution will consider any character entered exept N/n as "continue", if you want to avoid this:
int main()
{
char choice;
bool run = true;
while(run)
{
// Make your calculation
do{
cout<<"Would you like to perform other calculation?(Y/N)"<<endl;
cin >> choice;
choice = tolower(choice);//Put your letter to its lower case
}while (choice != 'n' && choice != 'y')
if(choice =='n'){
run = false;
}
}
return 0;
}

For some reasons whenever I enter y or Y, the program ends
The return statement is used to return control(and sometimes an optional value), to a functions caller. When return is used inside the called function, the function is terminated. From cppreference.com:
[return] terminates [the] current function and returns [a] specified value to the caller function.
(emphasis mine)
You may be under the impression that the statement return true inside your while-loop is returning the Boolean value of true to your while condition. It is not.
If your end goal is to create a yes/no style program that ends when the user enters "No/no", then you can to make use of the continue and break statements, or use a do/while loop.
Using continue and break
The continue statement is used to immediately skip to the next iteration of a loop, for or while, terminating the current iteration. From cppreference.com:
Causes the remaining portion of the enclosing for, range-for, while or do-while loop body to be skipped.
Used when it is otherwise awkward to ignore the remaining portion of the loop using conditional statements.
(emphasis mine)
The break statement is somewhat similar to continue, but instead of breaking the current iteration and skipping to the next one, it immediately breaks the entire program out of the while loop returning control to the outer-scope. From cppreference.com:
Causes the enclosing for, range-for, while or do-while loop or switch statement to terminate.
Used when it is otherwise awkward to terminate the loop using the condition expression and conditional statements.
(emphasis mine)
After examining the information above, you can modify your program to make use of continue and break, instead of return:
#include <iostream>
using namespace std; // This is for demonstration purposes ONLY
// never use this statement in your actual program. prefix cout and
// cin with std::
int main()
{
char choice;
while(true)
{
cout<<"Would you like to perform other calculations?(Y/N)"<<endl;
cin >> choice;
if(choice == 'Y'|| choice =='y'){
continue; // instead of returning, skip to the next iteration
// and ask again
}else if(choice =='N'||choice =='n'){
break; // return could be used here to break the while loop and
// terminate the program. But be explicit and use a statement specifically
// made for breaking out of loops
}
}
return 0;
}
Using a do/while loop
While the method above would work, I recommend using my second option-- a do/while loop. The do/while has the advantage o being shorter, and not having to make use of any kind of major control flow. From cppreference:
Executes a statement repeatedly, until the value of expression becomes false. The test takes place after each iteration.
If needed you could even add error checking to validate a users input:
#include <iostream>
using namespace std; // This is for demonstration purposes ONLY
// never use this statement in your actual program. prefix cout and
// cin with std::
int main()
{
char choice;
do { // do everything in the do block while...
cout <<"Would you like to perform other calculations?(Y/N)"<< endl;
cin >> choice;
if (choice != 'Y' and choice != 'y' and choice != 'N' and choice != 'n') // if needed add input
cout << choice << " is not a valid option. Try agian" << endl; // validation
} while (choice !='N' && choice !='n'); // the user input does not equal 'N'andr 'n'
return 0;
}
Output
Would you like to perform other calculations?(Y/N)
y
Would you like to perform other calculations?(Y/N)
Y
Would you like to perform other calculations?(Y/N)
n
References and Resources
cppreference.com
cplusplus.com

I just wrote some code and it works like a charm using "goto".
The code also included data validation as well. Many thanks to #Treycos.
int main()
{
char choice ='Y';
bool valid = true;
//some calculation
here:
int x =1+1;
cout<<x<<endl;
while(valid){
cout<<"Would you like to perform other calculation?(Y/N)"<<endl;
cin >> choice;
if(choice =='N' || choice =='n'){
break;
}
if(choice =='Y'||choice =='y'){
goto here;
}
else if(choice != 'N'&& choice != 'n'&&choice != 'Y'&&choice != 'y'){
cout<<"Invalid input."<<endl;
valid = true;
}
}
return 0;
}
Output:
2
Would you like to perform other calculation?(Y/N)
y
2
Would you like to perform other calculation?(Y/N)
Y
2
Would you like to perform other calculation?(Y/N)
$
Invalid input.
Would you like to perform other calculation?(Y/N)
n
Process returned 0 (0x0)
For uppercase n:
2
Would you like to perform other calculation?(Y/N)
N
Process returned 0 (0x0)

Related

Why the loop is not breaking and also the if condition isnt working as expected?

#include"std_lib_facilities.h"
int main()
{
int i = 0;
int len_password;
cout<<"How Long Should Be Your Password?\n";
while(i == 0){
cin>>len_password;
if(!cin && len_password > 15){
cout<<"Please enter an appropriate value:\n";
}
else{
break;
cout<<"success!";
}
}
}
I want this code to print success when the loop breaks...and the loop will only break if the condition in if statement is satisfied....but even after typing the right input the loop is not breaking and also when i enter wrong input it is not allowing me to input once again...
If you checking it's less then 15 then print should be before the break and you don't need the !cin
You need to print "success" before breaking out of the loop. Also, your check for !cin doesn't make sense.
Instead, you could check if the cin operation failed, and if so, you can clear the stream to take additional input:
while(!(std::cin >> len_password) || len_password > 15)
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Please enter an appropriate value:\n";
}
cout << "success";
The loop will keep executing until the user enters an appropriate value, and then "success" is printed outside the loop. This avoids any break statements within the loop.

Methods in which to fix poor while-switch loop?

My switch case is supposed to be within the while loop, but it is having complications. I want the loop to end when the user inputs 1,2, or 3, while continuing to loop if any other value.
#include <iostream>
using namespace std;
int main() {
int k = 0;
enum CompanyRole {EXECUTIVE = 1, MANAGER = 2, STAFF = 3};
cin >> k;
while((k != 1) || (k!=2) || (k!=3)){
switch(k)
{
case EXECUTIVE:
cout << "Executive\n";
break;
case MANAGER:
cout << "Manager\n";
break;
case STAFF:
cout << "Staff\n";
break;
default:
cout << "Wrong role. Enter again.\n";
cin >> k;
break;
}
std::cin >> k;
}
return 0;
}
Here whenever you have suppose value for k is 1 there is one conditional statement which evaluates to true and enters the loop. (This will also hold for k=2 or k=3).
It will be while((k != 1) && (k!=2) && (k!=3)). Think this way, earlier you were saying - you will continue to the loop if either of them is true. Because in c++ if either of the condition is true - the whole expression evaluates to true - which basically make the loop iteration.
Here by putting those && we are ensuring that it is not one of 1 ,2 or 3. That is what you wanted to achieve.
The condition satisfying which the control enters the loop is those very conditions which are taken into account in switch. Solution:- Redesign the code - more explicitly, put the switch cases after the while statetment. Make sure you understand what each component does and redesign.
I'd rewrite your code to look like this:
while((k != 1) && (k!=2) && (k!=3)){
std::cout << "Wrong role. Enter again.\n";
std::cin >> k;
}
switch(k) {
// same as before
}
Your while is acting as a trap for valid input, so you don't need to test for good input in there. Let the while naturally exit once you have a valid value for k, then operate on k. It also avoids a few other small issues in your code.
Since the loop is performed at least once, you should use a do-while instead of a while loop. A do-while loop is always performed at least once, so the test to see whether you exit the loop is done at the bottom, not at the top.
In addition to that, you could simply introduce a bool variable and set it to false if the input is "bad". This makes the code much easier to vision and to follow.
Example:
#include <iostream>
using namespace std;
int main()
{
int k = 0;
enum CompanyRole { EXECUTIVE = 1, MANAGER = 2, STAFF = 3 };
bool ok;
do
{
ok = true; // assume input is good
cin >> k; // get the input
switch (k)
{
case EXECUTIVE:
cout << "Executive\n";
break;
case MANAGER:
cout << "Manager\n";
break;
case STAFF:
cout << "Staff\n";
break;
default:
ok = false; // input is bad.
cout << "Wrong role. Enter again.\n";
break;
}
} while (!ok); // if input is bad, loop again
}
At the top of the loop, we assume the input is good (ok = true;), and if it's bad, set ok to false. Then the test is for ok being false.
The above is much easier to follow, no having to deal with getting logical and and or erroneously stated, basically not too much thinking is involved. If the input is "bad", just indicate it's bad and test for it.

Wrong values during a Do-While loop C++

I'm having some trouble during a do-while loop on my code.
It's about an interface class that makes a validation about the values that are typed by the user. I'm using Visual Studio 2012.
int Interface::requestOption(){
int option; //El problema está aquí
do{
cout<<"--------------------------------"<<endl;
cout<<"Type an option...";
cin>>option;
if(option<1 || option>8){
cout<<"Invalid value, type again "<<endl;
Sleep(2000);
system("cls");
menu();
}
}while(!(option>0 && option<9));
return option;
}
If I use the method for the first time, it returns the value that I actually typed. But when I call it again, while I debug, I notice that the value of option is -893453, and also, it doesn't allow me to type another number (cin >> option is not working).
The method is being called to interact within the next method:
void Control::studentsControl(){
int op;
do{
system("cls");
interEst->menu();
op = interEst->requestOption();
Lista<Students>* students= NULL;
students = U->getStudents();
switch(op){
//Eight options
//The 8th option is to return to the previous menu.
}while(op != 8);
}
Call std::cin.clear() after each iteration before enter new value.
!(option>0 && option<9) is True for -893453 !(False && True) == !False == True. why not use (option<1 || option>8) like in the if statement?

Prompting to run the program again: fixing if they put an invalid statement in

Morning!
My question: I state in the program to enter Y for yes and N for no. If the user enters yes, no, or a random string, it will say that it's an invalid input and ask again. But say the user enters "yes yes yes", it will output the invalid statement three times. How could I resolve this?
I also need to do something about the boolean because it serves no purpose as I break the loop if they say n, but nevermind that.
Here's a fragment of my code:
bool done = true;
string ans;
try {
coeff input = readCoeffs();
results result = equSolver(input);
outResults(input, result);
while (done == true) {
cout << "Would you like to run the program again (Y to run again, N to close)? ";
cin >> ans;
if (ans == "Y" || ans == "y") {
coeff input = readCoeffs();
results result = equSolver(input);
outResults(input, result);
}
else if (ans == "N" || ans == "n") break;
else cout << "Invalid input. \n";
}
}
catch (const char* msg) {
cerr << msg << endl;
}
It should be
while(done == false)
Done should be initialized to false, and in your loop, set done to true when they enter N or n. It's somewhat a style question, but it's usually best to avoid breaks unless there's a REALLY good reason.
For your invalid input issue, you are using
cin >> ans;
This is broken by whitespace, so in put of "l m n o p" is going to make the program say "invalid input" twice, then exit. Look into using getline if you want to process by line instead.
The answers are simple enough.
1.
You can use while(true) and get rid of the done flag. or instead of using break;, flip the done flag. (Btw, I think you either misnamed the variable, or you flipped the boolean values... it still works but semantically it makes no sense.)
2.
cin only reads up to the next whitespace, which can be a space. If you want to read the whole line, you need to use getline. So instead of
cin >> ans;
use
getline(cin, ans);
EDIT: I fixed which getline is used. Should be correct now.
Two possibilities that I came up with:
Use getline(cin, ans)
Set the limit to the amount of characters read as follows:
char input[100];
cin.getline(input,100);

Making an if condition return if its true or while return if its true

When the condition is true or false, how can I make it return back and ask the question again, making the user re-enter the value?
Here is what I want to implement:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main()
{
int n;
cout<<"Enter numbers. Press 5 to stop: ";
cin>>n;
bool tr=true;
while(tr)
{
if(n!=5)
cout<<"You entered "<<n; //How to make it return again, since its false? I keep getting infinite loops :( ;
else
tr=false;
}
return 0;
}
You need to prompt the user in the while loop, so that it occurs in each iteration:
int n;
bool tr = true;
while(tr)
{
cout << "Enter numbers. Press 5 to stop: ";
cin >> n;
if(n!=5) {
cout << "You entered " << n;
} else {
tr = false;
}
}
Just put all your code (except 'n' and 'tr' definition) in while loop as follow:
int main()
{
int n;
bool tr=true;
while(tr)
{
cout<<"Enter numbers. Press 5 to stop: ";
cin>>n;
if(n!=5)
cout<<"You entered "<<n;
else
tr=false;
}
return 0;
}
The other answers all work, and there is something to be learned about improving program flow from them, but I believe the trick you're asking for is the continue keyword, which skips the remainder of this iteration of the loop.
bool tr = true;
int n;
while (tr)
{
cout << "Enter numbers...";
cin >> n;
if (n != 5)
continue;
else
tr = false;
}
EDIT Part 1: On the continue keyword.
You want to make your code as readable as possible. In this example, its use is unnecessary (as the other posters have shown); but it is the answer to the question "How do I skip the rest of processing in this iteration of my loop and continue to the next iteration?". Usually, such flow-breaking directives actually make code harder to read; but sometimes the opposite is true. Anything (or, at least, almost anything) that can be accomplished with continue or break, can be accomplished without them, so if you're going to use them, you want to have a definite reason for doing so. Usually, when I use continue, it's because I'm looping through a collection of inputs and I want to skip processing the loop whenever the input isn't in the format I'm expecting. Something like this (pseudo-code)...
foreach (Input i in ReceivedInputs)
{
if (i.isBad())
{
cout << "Bad input";
continue;
}
// Do massive block of calculating here.
}
is easier to read than this...
foreach (Input i in ReceivedInputs)
{
if (i.isBad())
cout << "Bad input";
else
{
// Do massive block of calculating here.
}
}
because the second version makes it harder to track what scope you're in, if you're looking toward the end of the massive block of calculating. In this case, I gain code readability by continue, so I use it. But simple code probably shouldn't use it. The break keyword is similar, though it's a lot easier to come up with examples where break is beneficial.
EDIT Part 2: On multiple iterations
This is just an issue of setting up the loop; there are no magic keywords here. The shortest way I can come up with, is probably something like this:
int n = 0;
int numberToTake = 10;
for ( int numbersTaken = 0; numbersTaken < numberToTake; ++numbersTaken)
{
cout << "Enter numbers...";
int n = 0;
for (cin >> n; n != 5; cin >> n)
cout << "Try again.";
// Do whatever processing on n you want to do here.
}
Though I should point out that, doing it this way, the only value you will ever get from the user will be 5, and if he inputs anything that doesn't fit in an integer, you will get unexpected behavior.
EDIT 3: After reading the comment more thoroughly, I think you're just looking for is the more traditional use of the for loop.
No need for the exra bool variable.
The idiom can be: Infinitely loop until the user enters 5:
for(;;) { // Loops infinitely
cout << "Enter numbers. Press 5 to stop: ";
cin >> n;
if(n == 5)
break; // Exits the loop
cout << "You entered " << n; // Before the if if you want to print 5 as well
}