Im new to programing in a whole and I was wondering how I could loop my while loop. I'm making a calculator and i've gotten to a part where I have the program ask whether or not the user wants to end the program, if the user answers "Yes" the program will end; however I have noticed that if the user answers "No" the program will just keep on working and not ask the question again. Is there a way where I can have it ask the question again?
while (response != "Yes" && response != "No") {
cout << "Would you like to end the program? Yes or No" << endl;
cin >> response;
if (response == "Yes") {
calculator_running = false;
} else if (response == "No") {
calculator_running = true;
} else {
cout << "Please choose a valid response" << endl;
}
}
Best practice is to split code to smaller pieces to keep concerns separated.
bool promptYesNo(const std::string& reason)
{
std::cin.clear(); // clear any error flags on cin
std::cout << reason << "\nType \"Yes\" or \"No\": ";
std::string answear;
while (std::cin >> answear) {
if (answear == "Yes") return true;
if (answear == "No") return false;
std::cout << "Please select \"Yes\" or \"No\": ";
}
// here standard input has ended, so terminating application:
std::exit(1);
}
while (!promptYesNo("Would you like to end the program?")) {
...
}
Note that std::cin.clear(); will protect you from invalid state of std::cin. Most probably this is source of your problems. For example some part of program was reading int value, but you have provided a letters. This setts error flags on cin and any later reads will fail.
You need to put the calculator_running to be checked in the while-part of the loopo, something like this:
calculator_running = true;
while (calculator_running)
...
Lke this, once you enter "Yes", that variable will be put to false, and you'll jump out of the loop.
The main trick with while-loops is that you always need to set the condition to true, just before you start the while-loop.
I have noticed that if the user answers "No" the program will just keep on working and not ask the question again
That's what you told the program to do!
If you don't want an entry of "No" to end the loop, take it out of the condition:
while (response != "Yes") {
Or, use your boolean, which is a bit "cleaner" (but ultimately has the same effect):
while (calculator_running) {
Related
So the problem is: Write a program that prints the question "Do you wish to continue?" and reads the input. If the user input is "Y", "Yes", "YES", then print out "Continuing". If the user input is "N" or "No", "NO" then print out "Quit". Otherwise, print "Bad Input". Use logical operators.
So far this is all the code that I have written. I know that it is not complete, and I do not know what else I need to add to the code.
#include <iostream>
using namespace std;
int main() {
char response;
cout << "Do you wish to continue?" ;
cin >> response;
if (response == 'Y'){
cout << "Continuing";
}
else if (response == 'N'){
cout << "Quit";
}
else if (response != 'N' || 'Y'){
cout << "Bad input";
}
return 0;
}
Update: so I edited my code and it is still giving me a bunch of errors. It's making me frustrated lol. Keep in mind I'm a beginner and we haven't learned loops yet. Sorry for the headache!
#include <iostream>
#include <string>
using namespace std;
int main() {
char response;
string help;
cout << "Do you wish to continue?" ;
cin >> response, help;
if (response == 'Y' || help == "Yes" || help == "YES"){
cout << "Continuing";
}
else if (response == 'N' || help == "No" || help == "NO"){
cout << "Quit";
}
else if (response != 'N' || response != 'Y' || help != "Yes" || help != "YES" || help != "No" || help != "NO"){
cout << "Bad input";
}
return 0;
}
First off I think this is a great start. Sounds like you are new to C++ so here are some suggestions:
1) Your response variable can only contain a character. I would suggest including string and changing the response to take a string from the user for 'Y', "Yes", etc.
2) I suggest wrapping your code in a while loop with an exit condition.
3) Each of your logic branches should include a return integer. This will give the program an exit condition if the logical conditions are met.
I know I haven't given you the answers fully. If you are truly stuck, reply back and we can walk through.
A simple way is to simply convert the user's answer to uppercase or lowercase. By doing this, you can simply use the lower case.
For your loop, you could for example use a "do..while".
#include <iostream>
#include <string>
using namespace std;
int main() {
int stop = 0;
string response;
//Continue until the user choose to stop.
do{
//-------------
// Execute your program
//-------------
cout << "Do you wish to continue? ";
cin >> response;
//-------------
//Convert to lower case
for (string::size_type i=0; i < response.length(); ++i){
response[i] = tolower(response[i]);
}
//-------------
//Check the answer of the user.
if (response.compare("y") == 0 || response.compare("yes") == 0){
cout << "Continuing \n";
}
else if (response.compare("n") == 0 || response.compare("no") == 0){
cout << "Quit \n";
stop = 1;
}
else{
cout << "Bad input \n";
}
}while(stop == 0);
return 0;
}
Like you said in the question, we care about Y,Yes,YES,N,No and NO. For anything else we need to print "Bad Input". Think about how you'd be storing these responses (hint: Sam Varshavchik's answer).
Once you've taken care of extracting user input, you'd want to check what the user actually entered and proceed accordingly. From your question it seems "if else" would do. You need to change the conditionals for your "if else ifs" because
you have 3 conditions for one type of response: Y, Yes and YES need one output - "continuing" while N, No and NO require a different output - "Quit" and for all others we print "Bad input". Think about what your conditionals should be and your if statement should look something like:
if (response == "Y" || response == "Yes" || response == "YES")
and then handle the case accordingly. You'd want to do the same for your No conditions and finally handle the case for all others. I'd suggest having your code like so:
if( conditionals for Yes){
//Code for Yes input
}
else if( conditionals for No){
//Code for No input
}
else{
//Code for all other inputs
}
It is tempting to give you the full answer but think about how your program needs to flow and proceed from there, you've almost got it!
If you have more questions post here and we'd be glad to help!
I've just started learning the basics in C++ and currently am trying to make a program that does a few basic things. The problem I have is occurring in the pasted function below.
At this point it literally does nothing when it runs. All I'm trying to do it make it so the function runs over and over again forever, until the user enters the letter 'q'.
The function must keep running even if the user enters some random string, anything, 'q' is the only keystroke that should stop the loop.
I have tried toying around with 'cin.whatever" and haven't found success. If you have an answer please provide as much explanation as possible. Thank you!
void menu()
{
cin.clear();
cin.ignore();
char quit = 'w';
while (quit != 'q') // while loop to allow the user infinite tries
{
cout << "Which story would you like to play? Enter the number of the story (1, 2, or 3) or type q to quit: " << endl;
cin >> quit;
if (quit < '1' or quit > '3') // make sure the user picks a valid choice
{
cout << "Valid choice not selected." << endl;
}
if (quit == '1')
{
story1(); // run story 1
}
if (quit == '2')
{
story2(); // run story 2
}
if (quit == '3')
{
story3(); // run story 3
}
if (quit == 'q')
{
cout << "good bye" << endl;
break;
}
}
}
Try adding single quotes around your 1,2,3 like you did with the q. The cin is expecting a char to be entered so evaluate it as such. e.g: if (quit == '1')
I'm relatively new to C++ (and programming in general for the most part) and I'm taking an online course which follows along by teaching with the aim of building a game. In one of the console application projects we have to write code which asks the user if the user wants play the game again.The goal for that part of the program is to ask the user to reply by typing "y" or "n" only and re-ask the question if the user responds by doing something else.
I have attempted to write code which does this and as far as I can see the code works fine. My question is, is the code I wrote valid in the following sense:
Will the code successfully accomplish the outlined task?
Is code like this prone to more errors if it grows later?
The code I have follows. In the main function:
.
.
.
do
{
PlayGame();
}
while (AskToPlayAgain());
And the function definition for AskToPlayAgain along with an apt description:
bool AskToPlayAgain()
{
bool Play = true;
string response = "";
cout << "Would you like to play again? y/n... ";
getline(cin, response);
if (response == "y") { }
else if (response != "n")
{
cout << "Please enter a valid response." << endl;
// We want AskToPlayAgain called again to ask for a proper response again; however,
// just calling it outside a conditional will cause the current "Play" value to be returned.
// This value is true by default and this function will return it even if "n" is entered after
// an invalid response. As such, in this case, we want this function to be called in the event
// of an invalid response which will always happen and we don't want the return value of the nested
// AskToPlayAgain function to be returned, which is true by default unless the program has successfully exited.
// Furthermore, once the nested AskToPlayAgain returns false, we want the program to exit and not return the "Play"
// (which is set to true) by the higher level AskToPlayAgain.
if (AskToPlayAgain()) { }
else { return false; }
}
else
{
Play = false;
cout << "Thank you for playing! :D" << endl;
}
return Play;
}
Is the reasoning I presented in the code comments valid? Is there a test case where this would fail? I've tried a few test cases, but all of them worked.
Many thanks for any help on this!
There is nothing wrong with your recursive method but you can simplify this with a loop, and avoid the potential problems associated with recursion. Loops and recursion are closely related. if (response == "y") { } is not wrong but it's an odd programming practice. If you are not going to do anything upon reaching this condition then don't bother testing for it.
Another method with while loop:
bool AskToPlayAgain()
{
while(true)
{
string response;
cout << "Would you like to play again? y/n... ";
getline(cin, response);
if(response == "y")
{
return true;
}
else if(response == "n")
{
cout << "Thank you for playing! :D" << endl;
return false;
}
cout << "Please enter a valid response." << endl;
}
}
Edit
Another example with recursive function:
This time we add a counter value for demonstration.
If you run this program and keep giving invalid input, then counter will go up. It shows how the recursive function needs to wait for all other recursive functions to finish.
I added char buf[1000] which is not used. Its purpose is to cause problems!
Potential problem: each function needs to allocate 1000 bytes stack memory (plus memory for other stack variables in the function, and heap memory for std::string). This memory is not freed until the function exists, so it builds up. Stack limit in your program is a few mega bytes, so now there is a potential stack-overflow error.
bool AskToPlayAgain(int counter)
{
char buf[1000]; //<-- allocate lots of stack memory to cause problems!
cout << "counter start: " << counter << " - memory allocated\n";
cout << "play again? y/n... ";
string response;
getline(cin, response);
if(response == "y")
{
return true;
}
else if(response == "n")
{
cout << "Thank you for playing! :D\n";
return false;
}
cout << "invalid response\n";
bool result = AskToPlayAgain(counter + 1);
cout << "counter: " << counter << " - memory cleanup\n";
return result;
}
int main()
{
do
{
printf("play...\n");
} while(AskToPlayAgain(1));
return 0;
}
For this reason its better to use loops in favor of recursive functions. But then again, recursive functions are sometimes useful, and if memory allocation is under control (like in your example) and there is clear path to break the recursion, then go ahead and use it.
i would suggest that in your AskToPlayAgain() function, you do the checking of response == "y" and response == "n" and then do your else section. Although this won't affect your code much, it is certainly easier to read and understand, and if an issue does come up later on , you will not have to spend much time having to go through your code again.
i.e.
if (response == "y") { }
else if (response == "n"){
// your code
}
else {
// your code to handle the invalid response
}
Plus, as suggested in the comments and in the answer by #Barmak Shemirani, It would be better to just use a loop to accomplish this task of repeated asking until a valid response. It's "cheaper" than having multiple function calls.
hi i am new to c++ and i dont understand why my while statement doesnt work now. it was working when i tried to do it earlier.
Full code is available at: http://pastebin.com/aeH5fKwh
basically here is the while loop (i excluded all the unnecessary parts, i left the inside of the while loop intact for viewing purpose)
int main()
{
unsigned int seed;
char input;
bool done;
for (int round = 0; round < 5; round++)
{
done = false;
cout << "\nEnter seed: ";
cin >> seed;
cout << "\nRound 1" << endl;
while(!done)
{
cout << "\nDo you wish to draw another card [y][n]: ";
cin >> input;
while (input != 'y' && input != 'n')
{
cout << "Invalid input! Please enter [y][n]!" << endl;
cin >> input;
}
if (input == 'y')
{
dealExtra(playerHand, deck, gameInfo);
cout << "Your cards are ";
printHand(playerHand, gameInfo.playerCardCount);
}
else
done = true;
}
}
cout << endl;
return 0;
}
when i try entering anything that is not 'y', 'n', it will tell me that my input is invalid. But when i try to enter 'y' or 'n', it kinda just ignored it and nothing else happened.. i checked with cout statement and found that it manage to get into the if (input == 'y') statement, but it doesnt seem like it is doing anything else. Everything was fine till 20 minutes ago and i really couldnt figure out whats wrong.
Edit: i ran another test using "cout << '[' << input << ']' << endl;".. it seems like the program is able to get my first input, but then it just hangs there afterwards.. what i get is something like:
Do you wish to draw another card [y][n]: y
[y]
y
y
y
y
I compiled this on linux terminal using g++
if extra codes is needed, i'll edit and add them.. thanks!
When you ask for input from the console, most implementations buffer characters until a newline key is pressed.
After the newline is received, the first character of the buffer is returned. The newline still remains in the buffer as well as any extra characters.
In your case, the second cin >> input statement will read the newline from the buffer.
As an experiment, try entering "frog" and single step through your program. This should illustrate the case of residual characters in the buffer.
Try cin.ignore(1000, '\n') after the first cin >> input. The ignore method will eat up any remaining characters in the buffer until the newline is found.
Make below statements inactive
dealExtra(playerHand, deck, gameInfo);
printHand(playerHand, gameInfo.playerCardCount);
and check if it works, then try making one of the above statements active alternately to find out in which function the flow is getting lost. And so on.
If you feel lazy to run a debugger, and plan to use cout<< statements to find a hanging call, you should flush you cout:
( cout << "I am here and going to hang" ).flush() ;
Otherwise you can't see recent output just because it's still in the output buffer. Try this and you well might see what call hangs your program.
You have an infinite loop inside checkComputerHand:
bool done = false;
while(!done)
{
if(sum == 11 && checkAce == true)
{
computerHand[aceLocation].value = 11;
done = true;
}
if(sum > 11 && checkAce == true)
{
computerHand[aceLocation].value = 1;
done = true;
}
// What if checkAce wasn't true? Infinite loop!
}
Also, the first two lines of newGame do not make any sense:
void newGame(Card playerHand[], Card computerHand[], Statistics &gameInfo)
{
playerHand = '\0';
computerHand = '\0';
// ...
}
Array parameters are silently rewritten by the compiler as pointer parameters. So all you're doing is assigning the null pointer to those local pointers. Probably not what you intended...
I'm making a small program that uses a if else statement, but instead of using numbers to control the flow i want to be able to make the control work with with yes and no;
for example:
cout << "would you like to continue?" << endl;
cout << "\nYES or NO" << endl;
int input =0;
cin >> input;
string Yes = "YES";
string No = "NO";
if (input == no)
{
cout << "testone" << endl;
}
if (input == yes)
{
cout << "test two" << endl;
//the rest of the program goes here i guess?
}
else
{
cout << "you entered the wrong thing, start again" << endl;
//maybe some type of loop structure to go back
}
but I can't seem to get any variations of this to work, i could make the user type a 0 or 1 instead but that seems really stupid, i'd rather it be as natural as possible, users don't speak numbers do they?
also i need to be able to simply add more words, for example "no NO No noo no n" all would have to mean no
hopefully that makes some sense
also i would love to make this using a window but i've only learned basic c++ so far not even that and i cant find any good resources online about basic windows programming.
You're not reading in a string, you're reading in an int.
Try this:
string input;
instead of
int input = 0;
Also, C++ is case-sensitive, so you can't define a variable called Yes and then try to use it as yes. They need to be in the same case.
btw, your second if statement should be an else if, otherwise if you type in "NO" then it will still go into that last else block.
First of all, input must be std::string, not int.
Also, you've written yes and no wrong:
v
if (input == No)
// ..
// v
else if (input == Yes)
^^^^
If you want your program to work with "no no no ..", you could use std::string::find:
if( std::string::npos != input.find( "no" ) )
// ..
The same with "Yes".
Also, you could do this to be almost case-insensitive - transform the input to upper-case letters (or lower, whatever ), and then use find.This way, yEs will be still a valid answer.
bool yesno(char const* prompt, bool default_yes=true) {
using namespace std;
if (prompt && cin.tie()) {
*cin.tie() << prompt << (default_yes ? " [Yn] " : " [yN] ");
}
string line;
if (!getline(cin, line)) {
throw std::runtime_error("yesno: unexpected input error");
}
else if (line.size() == 0) {
return default_yes;
}
else {
return line[0] == 'Y' || line[0] == 'y';
}
}
string input;
cin >> input;
if (input == "yes"){
}
else if (input == "no"{
}
else {
//blah
}