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')
Related
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) {
I have this C++ code and I am trying to do the following:
Prompt the user to enter "p" to play or "q" to quit, if the user enters anything "p" the program will continue, if the user enters "q" program would just terminate and if they entered an invalid input, it would also terminate. How do I do that?.
Thank you,
Here is the code:
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int Umain = 0;
double Atemp = 0;
double Utemp = 0;
double Working = 0;
double Total = 0;
char Answer = 'x';
void displayOverview ();
void playOrQuit();
void promptNumber();
int main(){
displayOverview();
playOrQuit();
promptNumber();
return 0;
}
void displayOverview(){
}
void playOrQuit(){
string playOrNot;
cout << "If you want to play please press 'p' for play, and 'q' if you wish to quit\n";
cin >> playOrNot;
if(playOrNot == "p"){
cout << "Awesome, lets start playing !!! \n";
}if(playOrNot == "q"){
cout << "Alright then, see you soon !!\n";
}
}
void promptNumber(){
do{
cout << "Please Enter numbers between 1 and 12: ";
cin >> Umain;
cout << "\n";
for (Utemp = Umain; Utemp > 0; Utemp--)
{
cout << "Please enter a number: ";
cin >> Atemp;
Working = (Working + Atemp);
}
}while (Answer == 'y');
}
Just add a call to exit after you detect 'q' was pressed:
}if(playOrNot == "q"){
cout << "Alright then, see you soon !!\n";
exit(0); // <=== Add this here
Exiting with a 0 traditionally means the program exited in an expected fashion and without any errors.
The usual way to do this kind of thing is to have PlayOrQuit return a bool with true meaning "keep on playing" and false meaning "quit". Use that function to control a loop:
while (PlayOrQuit()) {
// game logic goes here
}
That way you can put any appropriate cleanup code after the game loop instead of having a brute-force exit from down inside the function.
There are a couple of ways you can achieve this.
But I suggest you include the stdlib.h library and use system("exit") right inside your else statements that is meant to exit the program.
Add end(), return 0 or exit(0).
Use u brain like, if you need this then i will remember nearest possible thing you spot from past.
So you never made these kind of mistake.
}if(playOrNot == "q"){
cout << "Alright then, see you soon !!\n";
exit(0);
}
I'm trying to validate input for a quit/return question in my program so the user is forced to enter either 'r' or 'q'.
I have managed to get it almost working. The problem is if the user enters 'r' or 'q' at the beginning followed by random letters then the program accepts that input. Any ideas on how to get the program to allow only a single 'r' or 'q' ?
void exit()
{
char choice;
bool badInput;
do
{
cout << "Press 'r' to return to the menu\nPress 'q' to quit the program\n\n" << endl;
cin >> choice;
badInput = cin.fail();
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
} while (badInput == true && choice == 'r' && choice == 'q' && (cin.peek() == EOF));
if (choice == 'q')
{
system("CLS");
cout << "Bye!\n";
system("PAUSE");
}
else if (choice == 'r')
{
system("CLS");
main();
}
else
{
exit();
}
}
You've got a very strange way of approaching this problem that's got a lot of issues. In particular, creating a function called exit() is problematic since that's a core function, and calling it recursively to try and get input is likewise not a good plan. You already have a loop, you just need to use it more effectively.
Likewise, main() is called automatically and you should never have reason to call it manually.
Here's a first pass rewrite:
void getInput()
{
char choice;
while (true)
{
cout << "Press 'r' to return to the menu\nPress 'q' to quit the program\n\n" << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cin >> choice;
switch (choice)
{
case 'q':
system("CLS");
cout << "Bye!\n";
system("PAUSE");
exit(0);
break;
case 'r':
system("CLS");
doMain();
break;
}
}
}
This obviously needs more work, but at least should theoretically function. In your original code you're demanding that the input value be simultaneously two different things which is an impossibility, that code will never work.
I'd also encourage you to stop doing things like system("CLS") and system("PAUSE") and instead do something in C++ natively. That's not portable code and it's terribly clunky as it depends on commands from 1980s DOS.
Handling the input
Most implementation use a buffered cin, so that input will only be returned once the user press enter. If this is not acceptable to you, you'll have to use OS-dependent functions.
If it's ok for you, then if you read a char, only the first one will be handed over: the remaining chars until the enter will wait for subsequent reads. Therefore, instead of reading a single char, I propose you to read a full line into a string:
void want_exit()
{
const string message="Press 'r' to return to the menu\nPress 'q' to quit the program\n";
string line;
cout << message << endl;
while (getline(cin, line) && line.length()!=1
&& tolower(line[0])!='y' && tolower(line[0])!='n')
{
cout << "Invalid input" <<endl << message <<endl;
line.resize(0);
}
Now line contains either a single valid char, or it is empty (in case of premature eof, meaning, that there was an input redirection and that there will anyway be no more input).
Processing the input
You can't call recursively main(): you should instead return from the function, and organize the calling function so to continue the process
if (line.empty() || tolower(line[0])!='y' ) {
system("CLS"); // This is non portable
cout << "Bye!\nPress enter...";
cin.getch(); // as good as system("PAUSE");
std::exit(0); // be aware of the naming issue !
}
return;
}
The calling function (main() ?) would then use it in a loop:
while (...) {
...
if (...)
want_exit();
}
I have tried many things and i can not seem to figure out why this program will not stop the code if you select N when it prompts to try again or not.
I feel as though i had this working earlier, but i can not find any code from when it was working, and i see no reason this should not work. Can anyone help out?
#include <iostream>
using namespace std;
int main ()
{
char color[10];
char reboot, yes_no;
start:
cout << "What color is the light?\n";
cin >> color;
//if the light is Green
if (!strcmp(color, "green")) {
cout << "The light is Green, you may go ahead and drive thru the intersection.\n";
} else if (!strcmp(color, "Green")) {
cout << "The light is Green, you may go ahead and drive thru the intersection.\n";
//if the light is Yellow
} else if (!strcmp(color, "yellow")) {
cout << "The light is Yellow, safely stop at the intersection, or proceed thru.\n";
} else if (!strcmp(color, "Yellow")) {
cout << "The light is Yellow, safely stop at the intersection, or proceed thru.\n";
//if the light is Red
} else if (!strcmp(color, "red")) {
cout << "The light is Red, you need to stop.\n";
} else if (!strcmp(color, "Red")) {
cout << "The light is Red, you need to stop.\n";
}
//non recognised input
else{
cout << "\nYour input was not recognised...Would you like to restart? (Y/N)\n";
cin >> yes_no;
if(yes_no == 'Y'||'y'){
goto start;
}
}
//restart program
restart:
cout << "\nWould you like to run the program again? (Y/N)\n";
cin >> reboot;
if(reboot == 'Y'||'y'){
goto start;
}
return 0;
}
Your condition is not well formed it should be
if( (reboot == 'Y') || (reboot == 'y') )
{
goto start;
}
As it is, it always evaluates to true since 'y' evaluates to true and true || anything always gives true.
Same thing applies to yes_no check.
EDIT Since you are having trouble, I made a simple program to test it more easily, this should work as expected:
#include <iostream>
using namespace std;
int main()
{
char yes_no;
while (true)
{
cout << "Enter 'N or 'n' to quit\n";
cin >> yes_no;
if(yes_no == 'N'|| yes_no == 'n')
break;
}
return 0;
}
These 2 lines looks a bit strange
if(yes_no == 'Y'||'y')
if(reboot == 'Y'||'y')
maybe you meant below instead??
if(yes_no == 'Y' || yes_no == 'y')
if(reboot == 'Y' || reboot == 'y')
Starting with the real reason your code doesn't work - operator precedence and associativity:
reboot == 'Y'||'y'
always returns true, since it's parsed as (reboot=='Y')||'y'. If you want to test if reboot is equal one of the two chars, test it like that: reboot=='Y'||reboot=='y'.
That should fix your code. Although here are some advices:
Don't use the goto statement. You can loop your code using loops (while, for or do while).
If you're using C++, use std::string for storing text, you can then use text=="some Text" instead of testing the output of strcmp.
For future reference on operator precedence, you can always check Wikipedia.
I need to figure out how to validate 2 conditions.
Check if a previous number has been played.
Check if the number is between 1 and 9.
In either case, it should loop back to the beginning. With the first situation, it shouldn't run till the user enters a number that hasnt been played.
do
{
cout << "Interesting move, What is your next choice?: ";
cin >> play;
Pused[1] = play;
if(play != Pused[0] && play != cantuse[0] && play != cantuse[1] )
{
switch(play)
{
default:
cout << "Your choice is incorrect\n\n";
break;
}
}
}while(play != 1 && play != 2 && play != 3 && play != 4
&& play != 5 && play != 6 && play != 7 && play != 8 && play != 9);
Dis_board(board);
Instead of do-while loops, i like to use the combination of infinite loops + break statements, like this:
cout << "What is your first choice? ";
while (true)
{
// Input the choice, including validation
// Do the move
if (game_over)
break;
cout << "Interesting move; what is your next choice? ";
}
In the code above, the two comments represent code, which may itself contain loops. In order to reduce confusion, you might want to stuff this code into a separate function. For example, to input the choice:
while (true)
{
cin >> play;
bool is_illegal =
play == cantuse[0] ||
play == cantuse[1] ||
play < 1 ||
play > 9;
if (is_llegal)
cout << "Your choice is incorrect; please enter again: ";
else
break;
}
Note: to implement good handling of user errors, you also have to account for the case when the user enters nonsense instead of a number; look up istream::ignore and ios::clear for that.