Clearing input buffer - c++

I am writing a program, the program is basically a guessing game. Computer displays a number and the user has to guess whether their number is higher, lower or correct. I have already made the program and its all dandy, but the only not dandy part is that I cannot figure out how to get rid of the input buffer when the user decides to play the game again. Every time the user wants to play the game, the game starts again but with the same input as the last game. I have tried putting cin.clear() in any spot I could think and also cin.clear(). But it just seems to not work. How do I clear the input?
#include <iostream>
using namespace std;
int main ()
{
int num1 = 100;
char choice;
num1 = num1 / 2;
do
{
cout << "My guess is " << num1 << ". " << "Enter 'l' if your number is lower, 'h' if it is higher, 'c' if it is correct: ";
cin >> choice;
cin.clear();
if (choice == 'h')
{
num1 = num1 + 100;
num1 = num1 / 2;
}
if (choice == 'l')
{
num1 = num1 + num1;
num1 = num1 - 11;
num1 = num1 / 2;
}
if (choice == 'c')
{
cout << "Great! Do you want to play again (y/n)?: ";
cin >> choice;
}
} while (choice != 'c' || choice == 'Y' || choice == 'y' || choice == 'n' || choice == 'N');
return 0;
}

In order to restart the game, you need to reset num1. Put the inital value in a variable that you don't change.
const int init = 100;
char choice;
int num1 = init / 2;
When the computer has guessed correctly:
if (choice == 'c')
{
num1 = init / 2; // reset
cout << "Great! Do you want to play again (y/n)?: ";
cin >> choice;
}
You could also leave the loop condition at:
} while(choice != 'N' && choice != 'n');
You should also work on the divide and conquer algorithm. For the computer to be effective, it should always make a guess in the middle of the range that is still possible, and that's not what it's doing right now. It jumps up and down, even outside the established range. An alternative could be to keep two variables to be able to shrink the possible range effectively. You could also do two separate loops, one inner loop for guessing the number and one outer that only asks the user if he/she wants to play again.
Example:
#include <iostream>
int main() {
const int initlo = 1;
const int inithi = 100;
char choice;
do {
std::cout << "Think of a number [" << initlo << "," << inithi << "]\n";
int numlo = initlo; // initialize the range
int numhi = inithi;
int guess;
do {
guess = (numlo + numhi) / 2; // guess in the middle of the range
std::cout
<< "My guess is " << guess << ". "
<< "Enter 'l' if your number is lower, 'h' if it is higher, 'c' "
"if it is correct: ";
std::cin >> choice;
if(choice == 'h') // must be in the range (guess,numhi]
numlo = guess + 1;
else if(choice == 'l') // must be in the range [numlo,guess)
numhi = guess - 1;
// exit the loop if the user cheats or the answer is correct
} while(numlo <= numhi && choice != 'c');
if(choice == 'c') std::cout << "Great! ";
else std::cout << "Cheater! ";
std::cout << "Do you want to play again (y/n)?: ";
std::cin >> choice;
} while(choice == 'Y' || choice == 'y');
std::cout << "Bye\n";
}

Related

Looping assignment in C++

My assignment is utilizing loops. The program should accept input for the sales of 3 employees (Mary, Tom, and Chris). The flow should be as follows:
Initial? > number of sales to enter > enter sale amounts > display commission for sale at 17% > adds commission and sales to the respective variables >> continue until 'z' is input for inputSalesPerson >> display information
So I am trying to figure out why my return value for the tempComm variable isn't returning the correct value. If i was to enter 't' for variable inputSalesPerson it puts me into the switch case 't' no problem. Input number of sales and that works. But when I get to entering the salesAmount and then displaying commission it will not calculate correctly.
Also if I enter 'z' or 'Z' as the inputSalesPerson it will not end the program. I have a lot to go on this.
#include <iomanip>
#include <iostream>
using namespace std;
int main()
{
int salesT = 0, salesC = 0, salesM = 0;
double amountT = 0, amountC = 0, amountM = 0;
double commT = 0, commC = 0, commM = 0;
double commRate = (17/100);
int num_sales;
double salesAmount, totalSales, tempComm;
char inputSalesPerson;
do
{
cout << "Enter the sales person's initial (\"Z\" to quit): ";
cin >> inputSalesPerson;
while(inputSalesPerson != 't' && inputSalesPerson != 'T' && inputSalesPerson != 'm' && inputSalesPerson != 'M' && inputSalesPerson != 'c' && inputSalesPerson != 'C' && inputSalesPerson != 'z' && inputSalesPerson != 'Z')
{
cin.get();
system("cls");
cout << "Invalid input for employee. Please Input (T)om, (C)hris, (M)ary, or (Z) to End : ";
cin >> inputSalesPerson;
}
switch(inputSalesPerson)
{
case 't' :
case 'T' :
system("cls");
cout << "Enter the number of sales : ";
cin >> num_sales;
while(num_sales < 1 || num_sales > 5)
{
system("cls");
cout << "Invalid number of sales. Please enter a value between 1 and 5 : ";
cin >> num_sales;
}
salesT += num_sales;
for(int i = 0; i<num_sales; i++)
{
cin.get();
system("cls");
cout << "Enter the sale amount : ";
cin >> salesAmount;
while(salesAmount < 0)
{
cin.get();
system("cls");
cout << "Invalid sale amount. Please enter a positive amount : ";
cin >> salesAmount;
}
tempComm = salesAmount + (salesAmount * commRate);
cout << fixed << setprecision(2) << "Commission earned by tom on this sale is : " << tempComm << endl;
cin.get();
amountT += salesAmount + tempComm;
commT += tempComm;
totalSales += amountT;
}
break;
}
}while(inputSalesPerson != 'z' || 'Z');
return 0;
}
****EDIT****
Thank you for the information on single-step debugging. Thanks to that comment I was able to learn about using the debugging tool more in depth and that helped me get everything working a bit better.
I've commented your code at the areas that need fixing. Also, there's a problem with using cin.get() all over the place. I assume that you do this to discard the return character after each input. But if the standard input (cin) is empty when you call cin.get() it will block the program until something is input. This is what happens when you enter more than one num_sales:
for (int i = 0; i<num_sales; i++)
{
cin.get();
It handles the first fine, but on the second loop you get:
Enter the sale amount : 20
Commission earned by tom on this sale is : 23.40
// cin.get() blocks here, with no user instructions to enter the next sale amount
I've commented out all the cin.get(). It will still work the same because the cin operator >> discards whitespaces and newlines, so even if there is a \n newline character still in the buffer, the next time you do something like cin >> num_sales it will discard the newline anyway.
#include <iomanip>
#include <iostream>
using namespace std;
int main()
{
int salesT = 0, salesC = 0, salesM = 0;
double amountT = 0, amountC = 0, amountM = 0;
double commT = 0, commC = 0, commM = 0;
double commRate = (17 / 100.0); // Int divided by int will round to an int.
// commRate is 0.0. Divide by double instead (17 / 100.0)
int num_sales;
double salesAmount, totalSales = 0, tempComm; // totalSales needs to be initialised to
// zero, otherwise it holds a garbage value.
char inputSalesPerson;
do
{
cout << "Enter the sales person's initial (\"Z\" to quit): ";
cin >> inputSalesPerson;
while (inputSalesPerson != 't' && inputSalesPerson != 'T' && inputSalesPerson != 'm' && inputSalesPerson != 'M' && inputSalesPerson != 'c' && inputSalesPerson != 'C' && inputSalesPerson != 'z' && inputSalesPerson != 'Z')
{
//cin.get();
system("cls");
cout << "Invalid input for employee. Please Input (T)om, (C)hris, (M)ary, or (Z) to End : ";
cin >> inputSalesPerson;
}
switch (inputSalesPerson)
{
case 't':
case 'T':
system("cls");
cout << "Enter the number of sales : ";
cin >> num_sales;
while (num_sales < 1 || num_sales > 5)
{
system("cls");
cout << "Invalid number of sales. Please enter a value between 1 and 5 : ";
cin >> num_sales;
}
salesT += num_sales;
for (int i = 0; i<num_sales; i++)
{
//cin.get();
//system("cls");
cout << "Enter the amount for sale number " << i+1 << ": ";
cin >> salesAmount;
system("cls"); // I would put the clear here,
// Otherwise the user can't see the commission made by Tom
while (salesAmount < 0)
{
//cin.get();
system("cls");
cout << "Invalid sale amount. Please enter a positive amount : ";
cin >> salesAmount;
}
tempComm = salesAmount + (salesAmount * commRate);
cout << fixed << setprecision(2) << "Commission earned by tom on this sale is : " << tempComm << endl;
//cin.get();
amountT += salesAmount + tempComm;
commT += tempComm;
totalSales += amountT; // I think you mean to add salesAmount maybe?
}
break;
}
} //while (inputSalesPerson != 'z' || 'Z');
// Even if { this ^^^^} is false, ^^^ this is always
// 'Z' char will convert to bool, any non-zero value is true.
while (inputSalesPerson != 'z' && inputSalesPerson != 'Z');
return 0;
}

What is wrong with my do...while logic, and continue logic?

I'm new to stackoverflow, and also somewhat new to programming, so please don't mind my poor formatting of the code. I have two problems with my code.
My continue statement, which I'm using to continue the loop if the player types 'y' or 'Y', doesn't work. It terminates the program after only getting the guess correctly, which leads me to:
2.My continue counter goes past 0 without stopping, and I just can't see my error in the logic of the program.
I can't see the problems with my logic.
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <ctime>
#include <random>
using namespace std;
int getNumber(); //random number prototype
double getScore(); //gets score
int chances = 7; //chances to guess with
int main()
{
int guess = 0,
random;
char retry = 'y'; //initialize retry to 'y'
cout << "This is a random number guessing game. " << "You will be guessing between 1-100."
<< "You have 7 chances. Good luck! \n \n" << endl;
random = getNumber(); //give the function a variable
do
{
cout << random << "\n" << "\n";
chances--;
cout << "Enter your guess: ";
cin >> guess;
if (guess == random)
{
cout << "You have won the game! " << "Your score was: " << getScore();
cout << "Would you like to retry? (Y or N): ";
cin >> retry;
if (retry == 'y' || retry == 'Y')
{
chances = 7;
guess = 0;
getNumber();
continue; //player can retry the game
}
else if (chances == 0)
{
cout << "You have no chances left. Retry? (Y or N): ";
cin >> retry;
if (retry == 'y' || retry == 'Y')
{
chances = 7;
guess = 0;
getNumber();
continue;
}
}
return 0;
}
else if (guess != random)
cout << "You got it wrong. \n" << "You have: " << chances << " chances left" << endl << endl;
else
cout << "Incorrect Input. Please type a number." << endl << endl;
} while (guess != random);
return 0;
}
int getNumber()
{
unsigned seed = time(0); //seed the random number
srand(seed);
int randNum = rand() % 10 + 1; //random number in the range of 1-10
return randNum;
}
if (retry == 'y' || 'Y')
This is incorrect logic, which is why your code does not work the way you want it to. You want it to be:
if (retry == 'y' || retry == 'Y')
Fix this logic error in your other if-else statements as well.
You'll wanna take a look at this
Your continue statement is jumping to the end and checking the condition, guess != random, which evaluates to false and exits the do while. What you need to do is reset guess to a value such as 0 so that the condition does evaluate to true.

Postfix Notation Calculator

I'm trying to code a postfix calculator, but I keep running into two issues-
first: When the calculator encounters a space, it sort of just exits immediately
second: when it encounters a non operator/non digit (ie- z) it doesn't display the error message that I coded.
int main()
{
stack <int> calcStack;
string exp;
char ans;
cout << "\nDo you want to use the calculator?" << endl;
cin >> ans;
while (ans == 'y')
{
cout << "\nEnter your exp" << endl;
cin >> exp;
for (int i = 0; i < exp.size(); i++)
{
if (isspace(exp[i]))
{
}
else if (isdigit(exp[i]))
{
int num = exp[i] - '0';
calcStack.push(num);
}
else
doOp(exp[i], calcStack);
}
while (!calcStack.empty())
{
calcStack.pop();
}
cout << "\nDo you want to use the calculator again?" << endl;
cin >> ans;
}
system("pause");
return 0;
}
This is the function--
void doOp(const char & e, stack <int>& myS)
{
if (myS.size() == 2)
{
int num1, num2, answ;
num2 = myS.top();
myS.pop();
num1 = myS.top();
myS.pop();
if (e == '+')
answ = num1 + num2;
else if (e == '-')
answ = num1 - num2;
else if (e == '*')
answ = num1 * num2;
else if (e == '/')
answ = num1 / num2;
else if (e == '%')
answ = num1 % num2;
else
cout << "\nError- Invalid operator" << endl;
cout << "\nCalculating..." << endl << answ << endl;
myS.push(answ);
}
else
cout << "\nInvalid stack size- too few, or too many" << endl;
}
In your main loop, you're reading strings with the string extractor:
cin >> exp;
THe string extractor is space sensitive. So as soon as a space char is encountered in the input, the string reading stops, and the witespace is not included in exp.
If you want to get a full line including spaces, you should opt for:
getline (cin, exp);
Edit:
The issue you experience with getline() is realted to the char extraction when you ask if user wants to use the calculator. Entering y is not sufficient. So you'l enter yenter. Only the y will be put into ans, so that getline() will start reading an empty line.
To solve this, update your initial input:
cin >> ans; // as before
cin.ignore (INT_MAX, '\n'); // add this to skip everything until newline included
Here an online demo showing that it works (including error message in case of wrong operator)

Trouble with guessing game

I need to do a Guessing game where the program generates a random number and the user has to guess the number. If the user guesses the number in less than 10 guesses the program congratulates them and lets them know they were under 10 guesses. If they were above 10 guesses then it lets them know it was above 10, etc.
The problem I'm facing is if, for example, the user guesses the number in 3 tries and then decides to play again with a whole new other number, and this time guesses it in 8 tries, instead of still congratulating them because it was under 10 tries, it counts the 3 tries from the previous game. This then leads the program to tell them they were over 10 tries, even though they were not. I don't know how to fix this. The code I've done so far is as follows:
int main()
{
srand(time(0));
int guess;
int number;
char selection = 'y';
int numberOfGuesses=0;
while(selection == 'y' || selection == 'Y')
{
number = rand() % 1000 + 1;
cout << "I have a number between 1 and 1000.\nCan you guess my number?\nPlease type your first guess: ";
cin >>guess;
do
{
if(number > guess)
{
cout << "Too low. Try again: " << endl;
cin >> guess;
numberOfGuesses++;
}
if (number < guess)
{
cout << "Too high. Try again: " << endl;
cin >> guess;
numberOfGuesses++;
}
}
while(number != guess);
if(numberOfGuesses < 9)
{
cout << "You guessed the number in less than 10 guesses!\n Would you like to play again (y or n)?";
cin >> selection;
}
else if(numberOfGuesses > 9)
{
cout << "You guessed the number\n Would you like to play again (y or n)?";
cin >> selection;
}
else if(numberOfGuesses == 9)
{
cout << "You guessed the number.\n Would you like to play again (y or n)?";
cin >> selection;
}
}
return 0;
}
The problem is that you are not resetting the counter.
Just put int numberOfGuesses=0; within the while loop:
while(selection == 'y' || selection == 'Y')
{
int numberOfGuesses=0;
....
}
You need to set numberOfGuesses to 0 before every game. Your program only sets it once when the program first launched.
You are not resetting numberOfGuesses to zero after each round. You can solve the problem using one of couple of methods.
Reset the value of numberOfGuesses to zero at the end of the first while loop.
while(selection == 'y' || selection == 'Y')
{
...
numberOfGuesses = 0;
}
Don't define the variable until the start of that while loop. Define it as the first statement and initialize it zero.
while(selection == 'y' || selection == 'Y')
{
int numberOfGuesses = 0;
...
}

C++ Do-while loop stopping

I got an assignment where we make a cmd prompt show up and display a flashcard game for multiplication. After inputting a correct answer a prompt shows up and asks the user to go "Again? Y/N." after the second input answer the prompt to ask the user doesn't show up and it's stuck on a "congratulations" message. This happens when I write in code to randomly generate two numbers for the game twice. one outside the while loop, and one inside while loop. If I leave one out the 2nd code for the random numbers it will run fine but will only display the same numbers over again. what I'm asking is how do I fix it so that it won't get stuck after the second answer input?
sample code below:
#include <iostream>
using namespace std;
int main()
{
int num1, num2, ans, guess, count = 0;
char choice;
num1 = rand() % 12 + 1;
num2 = rand() % 12 + 1;
//first number generator.
ans = num1 * num2;
do
{
{
cout << num1 << " X " << num2 << " = ";
cin >> guess;
cout << "Wow~! Congratulations~! ";
count++;
num1 = rand() % 12 + 1;
num2 = rand() % 12 + 1;
//second number generator.
} while (guess != ans);
cout << "\nAgain? Y/N: ";
cin >> choice;
} while ((choice == 'y') || (choice == 'Y'));
//after two turns the loop stops. Can't make a choice.
cout << " Thanks for playing! Number of tries:" << count << endl;
return 0;
}
I'd guess the problem is because your loops aren't quite what you think they are.
do
{
The code above has started a do loop.
{
I suspect you intended to start another (nested) do loop here--but you left off the do, so it's just a block that gets entered, executed, and exited. Useless and pointless in this case.
cout << num1 << " X " << num2 << " = ";
cin >> guess;
cout << "Wow~! Congratulations~! ";
count++;
num1 = rand() % 12 + 1;
num2 = rand() % 12 + 1;
//second number generator.
} while (guess != ans);
You've formatted this as if the while were closing the nested do loop--but since you didn't actually create a nested do loop, this is just a while loop with an empty body. Its meaning would be more apparent with a little re-formatting:
// second number generator
}
while (guess != ans)
/* do nothing */
;
The problem can be found here:
do
{
{
cout << num1 << " X " << num2 << " = ";
cin >> guess;
As you can see, the second scope has no do statement. As a result it is only a codeblock.
You can solve it by writing a do statement for the second code block.
Because the do is not present in the second bracket ({), the while is interpreted as a while loop:
while (guess != ans);
or
while (guess != ans) {
}
this thus keeps looping until guess is not equal to ans. But since in the loop does not modify any of the two variables, the loop will keep iterating.
Other errors: note that the program is still incorrect, since it will claim you have answered the question, regardless of the answer. You can fix it by implementing this as follows:
int main()
{
int num1, num2, ans, guess, count = 0;
char choice;
do {
num1 = rand() % 12 + 1;
num2 = rand() % 12 + 1;
ans = num1 * num2;
do {
cout << num1 << " X " << num2 << " = ";
cin >> guess;
if(guess == ans) {
cout << "Wow~! Congratulations~! ";
} else {
cout << "No, wrong!\n";
}
count++;
} while (guess != ans);
cout << "\nAgain? Y/N: ";
cin >> choice;
} while ((choice == 'y') || (choice == 'Y'));
//after two turns the loop stops. Can't make a choice.
cout << " Thanks for playing! Number of tries:" << count << endl;
return 0;
}