calling function on while loop - c++

I'm making a calculator program but I already encounter a problem. Well, my code is in a loop that will call a function to display the choices and then ask the user to pick, a/s/m/d are the choices. If the input is on the choices, it will proceed to the next step. Otherwise, it will loop and then call the function again.
#include <iostream>
using namespace std;
void home()
{
cout << "\nChoose your operation:" << endl;
cout << "\tType [A] for Addition" << endl;
cout << "\tType [S] for Subtraction"<< endl;
cout << "\tType [M] for Multiplication" << endl;
cout << "\tType [D] for Division" << endl;
}
int main()
{
char operation;
bool no_operator = true;
int design = 73;
for (int i = 0; i < design; i++){
if (i == 25){
cout << " WELCOME TO CALCULATOR ";
i += 22;
}
else i == 72 ? cout << "*\n" : cout << "*";
}
while (no_operator){
home();
cout << "\nOperation: ";
cin >> operation;
if (operation == 'A' || operation == 'a')
{
cout << "\nIt will going to add numbers";
no_operator = false;
}
else if (operation == 'S' || operation == 's')
{
no_operator = false;
cout << "\nIt will going to subtract numbers";
}
else if (operation == 'M' || operation == 'm')
{
no_operator = false;
cout << "\nIt will going to multiply numbers";
}
else if (operation == 'D' || operation == 'd')
{
no_operator = false;
cout << "\nIt will going to divide numbers";
}
else
{
cout << "\tInvalid Input: You must enter A/S/M/D only\n";
//home();
}
}
return 0;
}
My problem is it will run the '''home()''' in else statement even if the input is correct on the second loop.
I want to stop the '''home()''' to be called when the input is correct

Your code works perfectly fine. Make sure you're inputting the correct letters.
Also for this code, a "do while()" loop would be better.

You program is working perfectly fine as the input is correct it does not show the home rather print the message it will going to divide etc.

Related

How can I clean this code up by using a loop?

Basically, this program allows a user to enter a sentence and depending on the users selection, it will show the middle character of the sentence, display it uppercase or lowercase, or backwards. Simple program, but I am new to programming so that may be the problem. I would like to figure out how to use loops instead of a ton of if statements. When I try to make some loops it breaks certain parts of the code but I am sure that is because I don't properly understand them. If you have any criticism or any advice on the code, I'd be happy to hear it. Thanks in advance!
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
int sel;
string sent;
bool validinput;
int i;
int x;
int j;
int a;
cout << "Welcome to my program. Enter a sentence and select one of the options below.\n";
cout << "Enter -999 to exit the program." << endl;
cout << "============================================================================" << endl;
cout << endl;
cout << "1. Display the middle character if there is one." << endl;
cout << "2. Convert to uppercase." << endl;
cout << "3. Convert to lowercase." << endl;
cout << "4. Display backwards." << endl;
cout << "Enter a sentence: ";
getline (cin, sent);
cout << "Selection: ";
cin >> sel;
if (sel < 1 && sel > 4)
{
cout << "Invalid input. Try again. Selection: ";
cin >> sel;
validinput = false;
}
else (sel >= 1 && sel <= 4);
{
validinput = true;
}
if (validinput == true)
{
if (sel == 1)
{
j = sent.length() / 2;
cout << "The middle character is: " << sent.at(j) << endl;
}
if (sel == 2)
{
for (int i = 0; i < sent.length(); i++)
{
if (sent.at(i) >= 'a' && sent.at(i) <= 'z')
{
sent.at(i) = sent.at(i) - 'a' + 'A';
}
}
cout << "Uppercase: " << sent << endl;
}
if (sel == 3)
{
for (int x = 0; x < sent.length(); x++)
{
if (sent.at(x) >= 'A' && sent.at(x) <= 'Z')
{
sent.at(x) = sent.at(x) - 'A' + 'a';
}
}
cout << "Lowercase: " << sent << endl;
}
if (sel == 4)
{
for (a = sent.length() - 1; a >= 0; a--)
{
cout << sent.at(a);
}
}
}
system("pause");
return 0;
}
Personally I would use the switch selection statement. I roughly did this just to explain a bit on how it can make your code more friendly and understandable.
int sel;
bool validInput = false;
switch(sel)
{
case 1:
//display middle char if there's one
case 2:
//convert to uppercase
case 3:
//convert to lowercase
case 4:
//display backwards
validInput = true;
break;
default: //if number does not meat 1, 2, 3 or 4
validInput = false;
break;
}
As you may notice, for case 1, case 2, case 3 and case 4, there's a break just to say that if the number is between 1 to 4; validInput is true.
Reference: Switch Selection Statement
i suggest using a switch. It will organize your code better. From looking at your code you seem to have used for and if wisely. But I suggest the if statements checking for the input be replaced with switch.

C++: Asking the user to enter a new number if the number they entered is wrong

I'm trying to get the program to loop again, up to three times, if the user entered a number that does not follow the function defined in the if statement. The code as is, only loops once and then exits. Did I type the for loop incorrectly or is it the if...else statement that is wrong?
#include <iostream>
using std::cout; using std::cin; using std::endl;
int main() {
cout << "Enter a positive odd number less than 40: ";
int num = 0;
for (int a = 0; a < 3; ++a);
cin >> num;
{
if (num < 40 && num > 0 && num % 2 == 1)
{
cout << "Thank you!" << endl;
}
else cout << "That is incorrect, try again!" << endl;
}
}
Did I type the for loop incorrectly or is it the if...else statement that is wrong?
Both. You should (1) remove the semicolon following the for statment; (2) move cin >> num into the for loop body; (3) add break; inside the if.
for (int a = 0; a < 3; ++a)
{
cin >> num;
if (num < 40 && num > 0 && num % 2 == 1)
{
cout << "Thank you!" << endl;
break;
}
else cout << "That is incorrect, try again!" << endl;
}
BTW1: Try to use the debugger, then you'll find out what happened in fact.
BTW2: The code will fail when cin >> num fails (e.g. user entered an invalid value), you might need to check the result of cin >> num, to process the case. Such as:
for (int a = 0; a < 3; ++a)
{
if (cin >> num)
{
if (num < 40 && num > 0 && num % 2 == 1)
{
cout << "Thank you!" << endl;
break;
}
else cout << "That is incorrect, try again!" << endl;
}
else
{
cin.clear(); // unset failbit
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // skip bad input
cout << "Wrong input, try again!" << endl;
}
}
bool isValid = false;
int num;
while(!isValid)
{
cout << "enter a positive odd integer " << endl;
cin >> num;
if(num < 40 && num > 0 && num % 2 == 1 )
{
cout << "thank you"<<endl;
isValid = true;
}
else
isValid = false;
}
Why not use some thing like this, it will loop until isValid = true which will only happen when your conditions are met?
I understand I guess, if you're doing a school project or some thing and you're forced to do it with a for loop but in general this would be a much better solution for some thing like this than a for loop!

C++ Function being called when it isn't supposed to

I'm nearly finished working on a small guessing game, but i have run into a problem I don't know how to work around.
The problem is with the check_guess function that is checking to make sure the guess being input is a number between 1 and 100.
When running the program the first time, everything works fine.
http://i.imgur.com/pprunDT.png (I would post images if my reputation weren't so low)
But every time after, where yes to play again is chosen, the program runs through the check_guess function and displays "Invalid Input" when it shouldn't
http://i.imgur.com/8OSnSJt.png
I'm not sure why the program is behaving this way.
The code for the entire program is here:
#include <iostream>
#include <cstdlib> //for rand
#include <ctime> //for time
#include <string>
#include <sstream> //for conversions from string to int
using namespace std;
int check_guess(int tries) { //function for limiting the input of guess
string guess = "";
int result = 0;
do {
getline (cin, guess);
istringstream convert(guess);
if ( !(convert >> result) || (result < 1 || result > 100) ) {
result = 0;
cout << "Invalid Input.\n" << endl;
cout << "You have " << tries << " tries: ";
}
} while (result == 0);
return result;
}
bool play_again() { //function for limiting the input of mode
bool quit;
string yn;
do {
cin >> yn;
if ( yn == "y" || yn == "yes" ) {
quit = false;
}
else if ( yn == "n" || yn == "no" ) {
quit = true;
}
else {
yn = "invalid";
cout << "Invalid input.\n\nEnter 'y' or 'n': ";
}
} while ( yn == "invalid" );
return quit;
}
int main()
{
srand(time(0)); //sets seed to be random
int mystery = 0; //defines mystery number
int guess = 0; //defines guess
int tries = 5; //defines trys
bool quit = false; //defines replay or quit
cout << "----------------------------------\n";
do { //while mode is not set to quit, keep playing
tries = 5; //resets tries each new game
mystery = rand() % 100 + 1; //sets mystery number to be random
guess = 0;
cout << "Pick a number between 1 and 100.\n\nYou have 5 tries: ";
while (tries != 0) { //loops until you have no tries left
guess = check_guess(tries);
if (guess == mystery) { tries = 0; } //if you guess right it ends the loop
else { tries--; } //guessing wrong lowers tries by 1
if ( tries != 0 && guess > mystery) {
cout << guess << " is too high.\n" << endl;
cout << "You have " << tries << " tries: ";
}
if ( tries != 0 && guess < mystery) {
cout << guess << " is too low.\n" << endl;
cout << "You have " << tries << " tries: ";
}
}
if (guess == mystery) { //if guess == mystery by time loop ends you win
cout << "Got it! You Win!\n" << endl;
}
else { //if not, you lose
cout << "You Lose! The number was: " << mystery << ".\n" <<endl;
}
cout << "-------------------\n";
cout << "Play Again?(y/n): "; //ask user to play again
quit = play_again();
cout << "-------------------\n";
if (quit == false)
cout << endl;
} while (quit == false);
cout << "----------------------------------" << endl;
return 0;
}
I'm not sure how to fix this.
this line:
cin >> yn;
only reads the 'y' but not the end of line. As a result, the next execution of this instruction
getline (cin, guess);
initializes guess to an empty string.
On line 19, import the code "cin.ignore();" without quotations.
So your code reads as
`int check_guess(int tries) { //function for limiting the input of guess
string guess = "";
int result = 0;
do {
getline (cin, guess);
istringstream convert(guess);
if ( !(convert >> result) || (result < 1 || result > 100) ) {
result = 0;
cin.ignore();
cout << "Invalid Input.\n" << endl;
cout << "You have " << tries << " tries: ";
}
} while (result == 0);
return result;
}
`
and so on. This stops input into the console briefly. You're code is reading the 'y' to try again as the input for the number when you restart as well. Putting in the little line cin.ignore(), stops it from inputting y twice.
Change play_again() to:
bool play_again() { //function for limiting the input of mode
bool quit;
string yn;
do {
getline (cin, yn);
if ( yn == "y" || yn == "yes" ) {
quit = false;
}
else if ( yn == "n" || yn == "no" ) {
quit = true;
}
else {
yn = "invalid";
cout << "Invalid input.\n\nEnter 'y' or 'n': ";
}
} while ( yn == "invalid" );
return quit;
}

Trying to use two diffrent arrays to ask and answer questions

I am trying to use 2 different arrays 1 for questions and the for answers but when I select the correct answer for any of the selected questions past "2" it always gives me incorrect answer and I cant see why can anyone held me please?
#include "Questions.h"
using namespace std;
//struct quiz
//{
// string question[MAXITEMS];
// string answers[MAXITEMS];
//};
const int MAXITEMS = 10;
int main ()
{
//quiz listQuiz[MAXITEMS];
//
//ifstream QuestionFile("Questions2.txt");
//char a;
//int count = 0;
//
// if(!QuestionFile) // file testing
// {
// cout<< " error opening file" << endl;
// return 1;
// }
//
// for (int i=0; i<MAXITEMS; i++)
// {
// QuestionFile>>listQuiz[i].
//return 0;
string question[MAXITEMS] = {"How_many_cards_of_each_suit_are_there?", "How_many_suits_are_there_in_a_standard_pack_of_cards?", "How_many_kings_are_in_a_standard_pack_of_cards?", "How_many_cards_are_in_a_standard_deck_of_cards?","How_many_black_suits_are_there_in_a_standard_pack_of_cards?", "How_many_red_suits_are_in_a_standard_pack_of_cards?", "Whats_the_number_of_the_card_that_comes_before_jack?", "How_many_cards_in_each_set_of_suits_are_there?", "What_is_the_lowest_number_in_a_standard_pack_of_cards?", "What_is_the_highest_number_in_a_standard_pack_of_cards?"};
string answers[MAXITEMS] = {"4", "4", "4", "52", "2", "2", "10", "13", "2", "10"};
int userInput = 0;
int tries = 0;
bool isGameOver = false;
cout << "select 1 to start game" << endl; //gives option to start and quit game
cout << "select 2 to quit game" << endl;
cin >> userInput;
if (userInput == 2)
{
isGameOver = true;
return 0;
};
// error message if 1 or 2 is not input
do
{
if (userInput!=1 && userInput!=2)
{
cout << " Your input is not valid! please try again:" << endl; // try switch cases for the different outcomes
cout << "select 1 to start game" << endl;
cout << "select 2 to quit game" << endl;
cin >> userInput;
if (userInput == 2)
{
isGameOver = true;
return 0;
};
while (!(cin >> userInput))
{
cin.clear(); // clear the error flags
cin.ignore(INT_MAX, '\n'); // discard the row
cout << "Your input is not valid! please try again: ";
cout << "select 1 to start game" << endl;
cout << "select 2 to quit game" << endl;
}
cout << userInput << endl;
}
// reprisent all characters as number to stop while roblem
// when game starts gives option to select question and shows all questions
if(userInput == 1)
{
// // system("pause");
// //return-1;
//// };
// while(QuestionFile) // while read is working
// {
//
// // for display
//QuestionFile >> question[count]; // read into array
//cout << count << " " << question << endl;
// count++;
// }
//
// for (int i = 0; i < count ; ++i)
// {cout << " array" << i << " is ::";
// cout << question[i]<< endl;
// }
// cout << question[0]; //reads data in cell
// //QuestionFile.close();
// //system ("pause");
do
{
cout << "select question" << endl;
for(int i = 0; i != MAXITEMS; i++)
{
cout << i << " " << question[i] << endl;
}
int selectQestion;
cin >> selectQestion;
if(selectQestion == 0||1||2||3||4||5||6||7||8||9 && tries != 2)
{
cout << "Enter your answer" << endl;
string userAnswer;
cin >> userAnswer;
while (!(cin >> userAnswer))
{
cin.clear(); // clear the error flags
cin.ignore(INT_MAX, '\n'); // discard the row
cout << "Your input is not valid! please try again: ";
}
if (userAnswer == answers[0])
{
cout << "Correct answer" << endl;
}
else{
cout << "incorrect try again" << endl;
tries++;
cin >> userAnswer;
if (userAnswer == answers[0])
{
cout << "Correct answer" << endl;
}
else
cout << "Incorrect" << endl;
}
}
if (selectQestion == 0||1||2||3||4||5||6||7||8||9 && tries == 2)
{
cout << "you can no longer answer this question" << endl;
cout << "try another question" << endl;
}
}
while(userInput == 1);
}
}
while(isGameOver == false);
}
I'm sure we've been through this before
if (selectQestion == 0||1||2||3||4||5||6||7||8||9 && tries == 2)
is incorrect. This version is correct.
if ((selectQestion == 0 || selectQestion == 1 || selectQestion == 2 || selectQestion == 3 || selectQestion == 4 || selectQestion == 5 || selectQestion == 6|| selectQestion == 7|| selectQestion == 8 || selectQestion == 9) && tries == 2)
But really you should use a little bit of logic and simplify, this version is even better
if (selectQestion >= 0 && selectQestion <= 9 && tries == 2)
Much better.
Fix that problem (you have it in at least two places) and if your program is still not working post again.
This doesn't make sense:
string question[MAXITEMS] = {"How_many_cards_of_each_suit_are_there?",
"How_many_suits_are_there_in_a_standard_pack_of_cards?",
"How_many_kings_are_in_a_standard_pack_of_cards?",
"How_many_cards_are_in_a_standard_deck_of_cards?",
"How_many_black_suits_are_there_in_a_standard_pack_of_cards?",
"How_many_red_suits_are_in_a_standard_pack_of_cards?",
"Whats_the_number_of_the_card_that_comes_before_jack?",
"How_many_cards_in_each_set_of_suits_are_there?",
"What_is_the_lowest_number_in_a_standard_pack_of_cards?",
"What_is_the_highest_number_in_a_standard_pack_of_cards?"};
string answers[MAXITEMS] = {"4", "4", "4", "52", "2", "2", "10", "13", "2", "10"};
To me, the answers and questions aren't in synch. And of course, it would be MUCH easier to deal with this if you have question and answer as part of a struct (or class):
struct QuestionAndAnswer
{
std::string question;
std::string answer;
}
QuestionAndAnswer qAndA[MAXITEMS] =
{
{ "Question 1", "Answer for question 1" },
{ "Question 2", "Answer for question 2" },
...
};
And this code doesn't do what you think it does:
if(selectQestion == 0||1||2||3||4||5||6||7||8||9 && tries != 2)
As suggested in another answer, you could do if (selectOption == 0 || selectOption == 1 ..., but I would suggest that you use a switch statement:
switch(selectOption)
{
case 0:
case 1:
... // more cases go here.
case 9:
if (tries != 2)
...
else // tries == 2
...
break;
default:
... Stuff to do when input was not a valid selection.
break;
}
It is much easier to read a switch than a 11 item long if-condition.
A further problem is this:
do {
...
} while(userInput == 1);
The variable userInput isn't changing inside that loop...
You also have a bug here:
if (userAnswer == answers[0])
You probably want to check that the answer is the answer to the selected question, not the first question.
May I suggest that you develop smaller parts of the code at a time - change one little thing, test it, if it doesn't work, figure out why, then write a bit more code. I've not even compiled or run your code, and I've spotted at least four distinct errors that - yes, I've done programming for over 30 years, so I have some experience in spotting errors.
This:
if (selectQestion == 0||1||2||3||4||5||6||7||8||9 ...)
is equivalent to:
if (selectQuestion == 1 ...)
The right hand side of the == sign is an expression for which C++ calculates a value and substitutes that value in place of that long series of ||'s.

CTRL+Z makes program loop infinitely in C++

Ok I have a problem here. I am making a slide puzzle game. The player is asked which piece he wants to move until the puzzle is solved. If the player wants to exit before, typing Q or q and pressing enter will do it. The program works just fine. BUT I am having one problem: if I insert CTRL+Z, the program will loop unexpectedly...
This is the piece of code that matters:
// analyzes user input
if (piece_to_move_string == "q" ||
piece_to_move_string == "Q")
{
cout << endl << "You chose to quit." << endl;
pressanykey();
break;
}
else
{
piece_to_move = atoi(piece_to_move_string.c_str());
if (1 <= piece_to_move && piece_to_move <= pow(puzzle_size,puzzle_size))
{
game_board = move_piece (game_board, piece_to_move);
}
else
{
cout << "Not possible.";
}
}
EDIT: but still doesn't work..
// analyzes user input
if (piece_to_move_string == "q" ||
piece_to_move_string == "Q")
{
cout << endl << "You chose to quit." << endl;
pressanykey();
break;
}
else if (cin.eof())
{
//do nothing
}
else
{
piece_to_move = atoi(piece_to_move_string.c_str());
if (1 <= piece_to_move && piece_to_move <= pow(puzzle_size,puzzle_size))
{
game_board = move_piece (game_board, piece_to_move);
}
else
{
cout << "Not possible.";
}
}
Ctrl+Z means "end of file" (assuming you're on Windows) so once the user hits that, your cin is in an unreadable state. Check for cin.eof():
if (cin.eof() || piece_to_move_string == "q" ||
piece_to_move_string == "Q")
{
cout << endl << "You chose to quit." << endl;
}