Non integer input causes infinite loop - c++

i created a code for my final project. where in the start the user is asked what calculator to use its either the average calculator or simple calculator. but if the user accidentally entered a non integer it causes in infinite error loop but if its an integer that is not in the choices it works because i created a while loop. i need help what do i need to do to prevent the infinite loop.
cout << 1. average calculator: << endl;
cout << 2. simple calculator: << endl;
cout << Enter the Number << endl;
cin >> choice;
while (choice > 2 || choice <= 1)
{
cout << "Error! Please choose a number between 1 and 2 only." << endl;
cout << "Enter the number again:";
cin >> choice;
}

You need to clear the input buffer. Also the condition in this if statement is incorrect
while (choice > 2 || choice <= 1)
It seems you mean
while (choice > 2 || choice < 1)
The while loop can be rewritten as do-while loop the following way
#include <limits>
//...
bool input_error = false;
do
{
input_error = false;
if ( not ( std::cin >> choice ) )
{
std::cin.clear();
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
input_error = true;
}
else if ( choice < 1 || choice > 2 )
{
input_error = true;
}
if ( input_error )
{
std::cout << "Error! Please choose a number between 1 and 2 only.\n";
std::cout << "Enter the number again: ";
}
} while ( input_error );

Instead of using a while loop, you could use a switch like this
switch(choice //this is the input)
{
case 1:
//the stuff you want to do
break; //always a break
case 2:
//more stuff
break;
default:
//throwing a error
std::cout << "Error, please pick a number between 1 and 2\n";
}
and if you want to repeat until you pick the right number, you could put the switch inside a do while loop like this
do
{
switch(choice)
{
//the stuff
}
}while(choice > 2 || choice < 1);
let's hope this will work
have a nice day.

cout << "1. average calculator:" << endl;
cout << "2. simple calculator:" << endl;
cout << "Enter the Number" << endl;
string stringInput;
getline(cin, stringInput);
int choice = atoi(stringInput.c_str());
while(choice < 1 || choice > 2) {
cout << "Error! Please choose a number between 1 and 2 only." << endl;
cout << "Enter the number again:";
getline(cin, stringInput);
choice = atoi(stringInput.c_str());
}
You should read whole line, store it in string, and then convert that string to integer using atoi(). atoi() expects c-string to be passed so std::string should be converted to c-string. It is done by stringInput.c_str().
I changed while condition(choice > 2 || choice <= 1) to (choice < 1 || choice > 2) because it says to enter number between 1 and 2, but with your condition entering number 1 would print "Error! Please choose a number between 1 and 2 only.".

Related

limit item entry C++

need to limit the ammount of items that can be entered into the array to 5. Tought i would use a do while loop but it just continues even after the 5 items have been entered. Any help would be appreciated
#include "stdafx.h"
#include <string>
#include <conio.h>
#include <iostream>
#include <array>
using namespace std;
string sItems[4] = {};
string sChoice = "";
int iItemPrice[4] = {};
int iNumOfItems = 0;
int iMenuChoice = 0;
int iCount = 0;
int main()
{
cout << "--------- Welcome to the program ---------\n\n Please pick from an option below: \n 1: Enter new items \n 2: Change item prices \n 3: Input sold items \n 4: Receipt for previous items sold\n ";
cin >> iMenuChoice;
switch (iMenuChoice)
{
case 1:
{
do {
cout << "--------- ENTER NEW ITEMS ---------\n\nPlease enter the item Name: ";
cin >> sItems[iCount];
cout << "\nPlease enter the price of: " << sItems[iCount] << "\n";
cin >> iItemPrice[iCount];
cout << "\nWould you like to enter another item? Y/N \n";
cin >> sChoice;
if (sChoice == "Y" || sChoice == "y")
{
++iCount;
++iNumOfItems;
}
} while (sChoice == "Y" || sChoice == "y" || iNumOfItems < 5);
cout << "you have entered the maximum ammount of items";
}
}
_getch();
return 0;
}
The loop condition sChoice == "Y" || sChoice == "y" || iNumOfItems < 5 means:
Loop as long as user answers "Y"
But at least 5 times regardless of user answer
If you want some other logic, like loop up to 5 times, then you can reflect that in the code.
Also check for failures. If you input a character when cin expects a number, it will enter a failed state and all subsequent input attempts will fail.
do {
cout << "--------- ENTER NEW ITEMS ---------\n\nPlease enter the item Name: ";
cin >> sItems[iCount];
cout << "\nPlease enter the price of: " << sItems[iCount] << "\n";
if (!(cin >> iItemPrice[iCount]))
break;
cout << "\nWould you like to enter another item? Y/N \n";
cin >> sChoice;
++iCount;
++iNumOfItems;
} while ((sChoice == "Y" || sChoice == "y") && iNumOfItems < 5);
And increase the array size from 4 to 5 if you want to support 5 items:
string sItems[5];
int iItemPrice[5];

How to evaluate number greater than and less than in the same while loop?

// DiceRollProject.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <time.h>
using namespace std;
int diceRoll(int max); // function definition
int getValidInteger();// function definition
int main() {
srand(time(0)); // seed the random number generator
int exitProgram = 0;
int guess, rollValue;
int maxRollValue = 6;
cout << "Hello! Let's play a dice game. Let me do the first roll for you.\n" << endl;
rollValue = diceRoll(maxRollValue);
cout << "In this roll, you got: " << rollValue << "\n" << endl;
do {
rollValue = diceRoll(maxRollValue);
cout << "What's your guess for the next roll? Enter an integer between 1 and " << maxRollValue << ": ";
guess = getValidInteger();
// TODO: Validate input
if (guess > rollValue)
{
cout << "The guess was too high!";
}
if (guess < rollValue)
{
cout << "The guess was too low!";
}
if (guess == rollValue)
{
cout << "You guessed correctly, congrats!";
}
cout << "In this roll, you got: " << rollValue << "\n" << endl;
// TODO: Evaluate result
cout << "Enter 1 to exit or any other integer to continue rolling ";
exitProgram = getValidInteger();
cout << "\n";
if (exitProgram == 1)
{
cout << "Sorry to see you go. Have a wonderful day!\n" << endl;
}
} while (exitProgram != 1);
return 0;
}
// Roll the die
int diceRoll(int max) {
int rollValue;
rollValue = (rand() % max) + 1;
return rollValue;
}
// Check if user entered an integer
int getValidInteger() {
int userInput;
cin >> userInput;
while (userInput < 1) {
if (userInput < 1)
{
cout << "Please enter a number greater than or equal to 1\n";
}
if (userInput > 6)
{
cout << "Please enter a number less than or equal to 6\n";
}
}
if (cin.fail()) {
cin.clear();
cin.ignore();
cout << "Please enter an Integer only ";
cin >> userInput;
cout << "\n";
}
return userInput;
}
I have a dice roll guessing game, I'm trying to evaluate the users input, to make sure that they can't enter a number less than 1 and greater than 6, unfortunately, with just my if statements, they can still enter these numbers, although a string is displayed that the input is not valid, I want to make a while loop that keeps asking them to enter a valid number equal or greater than 1 and equal to and less than 6, if the user keeps inputting an incorrect number, the while loop will keep asking them for a valid number, until they do enter one, which will then run the program as normally.
First of all, inside the while loop you have dead code.
while (userInput < 1) {
if (userInput < 1)
{
cout << "Please enter a number greater than or equal to 1\n";
}
if (userInput > 6)
{
cout << "Please enter a number less than or equal to 6\n";
}
}
Within the loop body, the first if is always true and the second one is always false. You should enter in a loop when the user writes an invalid input. This happens when (userInput < 1 or userInput > 6)
After the evaluation of the while's condition, you should ask the user to write input
do {
cout << "Please enter an Integer only ";
cin >> userInput;
if (userInput < 1)
{
cout << "Please enter a number greater than or equal to 1\n";
}
if (userInput > 6)
{
cout << "Please enter a number less than or equal to 6\n";
}
}while(userInput < 1 || userInput > 6);
So your condition that will keep you in the while loop is if the person guesses too high or too low. Inside the while loop I would add the updating condition or statement that you would like to repeat. So in your case, "your guess is too high" or " your guess is too low" and ask for their input again. I am not a pro but I would keep it simple by constructing 2 while loops, one for too high and one for too low just like your if statements. literally you can just change your first two if statements to while loops and adding an few extra lines of cout to ask the person to guess again and validate their input. I hope this helped.
from what I've understood you are looking for something like this:
int main (){
int my_magic_number=(rand()%6)+1,usernumber=-1;
bool state;
while (usernumber!=my_magic_number){
cin>>usernumber;
state = (usernumber<1||usernumber>6);
while (state) {
cout<<"You entered a number outside the range [1,6] please try again\n";}
cin>>usernumber;
state = (usernumber<1||usernumber>6);
}
if (usernumber!=my_magic_number) {/* do whatever you want */}
} //while loop
} // main

How do i check if input is an int in C++?

If the input is an integer, I want to set it equal to an integer variable.
If the input is a string, I will want to set it to a string variable, and later check if the string is "quit".
I don't know how to check it. I've looked for a built in function and found nothing.
while (true) {
int numberEntered;
string stringEntered;
cout << "enter a number to see if it is greater than 5: \n or enter \'quit\' to exit the program";
//I don't know what to do below here
cin >> ;
if (stringEntered == "quit") {
break;
}
if (numberEntered > 5) {
cout << "that number is greater than 5" << endl;
}
else {
cout << "not greater than 5" << endl;
}
}
cin >> numberEntered;
if (!cin.fail())
{
...
It may be more idiomatic to use:
if (cin >> numberEntered)
David S.'s answer is good. If you want to tidily handle garbage being entered after the line, here is another option (this is more complicated for your situation, but if you later want to expand your program to handle a lot of different input, then this way may come out to be simpler).
while( true )
{
string stringEntered;
cout << "enter a number to see if it is greater than 5: \n or enter \'quit\' to exit the program: " << flush;
// read the whole line, this ensures no garbage remains in the input stream
getline(cin, stringEntered);
if ( stringEntered == "quit" )
break;
// this checks that a number was entered and nothing else
istringstream iss(stringEntered);
int numberEntered;
char ch;
if ( !(iss >> numberEntered) || (iss >> ch) )
{
cout << "please try again. ";
continue;
}
// process the number
cout << "that number is " << (numberEntered > 5 ? "" : "not ")
<< "greater than 5." << endl;
}
You may need #include <sstream>.

How could I exit from do-while loop?

I have these block of codes that belong to a NIM subtraction game. The thing that I would like to implement is that user is going to be able play the game as long as he/she wants. Simply if user enters 999 program will exit, otherwise user will be playing until he/she enters 999. Here is my block of codes. I am not sure that I make a logical mistake or I need to add some specific exit code. Thanks for your time and attention.
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int total, n;
while(true){
cout << "Welcome to NIM. \nEnter 999 to quit the game!\nPick a starting total: ";
cin >> total;
if(total==999)
break;
while(true){
//pick best response and print results.
if ((total % 3) == 2)
{
total = total - 2;
cout << "I am subtracting 2." << endl;
}
else
{
total--;
cout << "I am subtracting 1." << endl;
}
cout << "New total is " << total << endl;
if (total == 0)
{
cout << "I win!" << endl;
break;
}
// Get user’s response; must be 1 or 2.
cout << "Enter num to subtract (1 or 2): ";
cin >> n;
while (n < 1 || n > 2)
{
cout << "Input must be 1 or 2." << endl;
cout << "Re-enter: ";
cin >> n;
}
total = total - n;
cout << "New total is " << total << endl;
if (total == 0)
{
cout << "You win!" << endl;
break;
}
}
}
return 0;
}
You are modifying total inside the loop. Just test after cin>>total at the beginning if total==999 and break if true, i.e.
if(total==999)
break;
and replace the do-while loop by a while(true){}
In the do-while loop you are trying to compare character literal '999' with variable total that has type int.
}while(total!='999');
Though this code is valid its result can be something else than you are expecting. Values of character literals with more than one symbol are implementation defined.
You have to write
} while ( total != 999 );
Also if the player will enter 999 you start to play with him though you have to exit the game.
So in my opinion it is better to use while loop. For example
while ( true )
{
cout << "Welcome to NIM. \nEnter 999 to quit the game!\nPick a starting total: ";
cin >> total;
if ( total == 999 ) break;
// ...
}
you have to do three corrections in your code to make it right
first you have to check if total is equal to 999, then break in your do loop just after getting the total from user
second - you have to put same condition in your first while loop
and lastly - instead of while(total!='999') u shall write while(total!=999) because it is integer

How do I break out of the for loop inside an inner while loop

For this loop, I need to be able to enter names into an array that has to be 100 elements long, and exit the array to read the names back once Q or q is entered, or the end of the array is reached. When I use this code, the program goes back to the beginning of the while loop without breaking the for loop.
for (int i = 0; i < 100; i++)
{
while (true)
{
cout << "Enter Player Name (Q to quit): ";
getline(cin,playerName[i]);
if (playerName[i] == "Q" || playerName[i] == "q")
break;
cout << "Enter score for " << playerName[i] << ": "<< endl << endl;
}
}
According to your description, it seems like the while (true) is completely redundant!!!
So you should simply do:
int i;
for (i = 0; i < 100; i++)
{
cout << "Enter Player Name (Q to quit): ";
getline(cin,playerName[i]);
if (playerName[i] == "Q" || playerName[i] == "q")
break;
cout << "Enter score for " << playerName[i] << ": "<< endl << endl;
}
At this point, you can use i in order to tell how many names have been entered by the user.
This is one of the rare circumstances where a judicious goto may be the best available option.
for (...)
{
while (...)
{
if (...)
goto exit_loop;
}
}
exit_loop:;
Some languages let you put a label on the for and use it in break, but C and C++ are not among them. It can also make sense to extract the entire loop nest to its own function, allowing you to use return to exit both loops, but this may not work in context.
I personally think that this use of goto is easier to understand than a boolean + if in the outer loop, as suggested in other answers, but reasonable people can disagree about that.
If I'm reading your question correctly, then you don't need the while loop. Without that while loop, break will exit the for loop, then you can enter a separate for loop (from 1 to 100) to print the contents of the array.
If the user enters less than 100 names at any point, then the second for loop will go from 1 to i, and output each array entry along the way.
I'm answering the title - wrap both loops in a function:
void foo()
{
for (;;)
while (true)
if (/* something */)
return;
}
I otherwise agree with barak manos, you don't even need two loops.
Add a boolean variable to tell you if the inner loop has broken:
bool broken = false;
for (int i = 0; i < 100; i++)
{
while (true)
{
cout << "Enter Player Name (Q to quit): ";
getline(cin,playerName[i]);
if (playerName[i] == "Q" || playerName[i] == "q") {
broken = true;
break;
}
}
cout << "Enter score for " << playerName[i] << ": "<< endl << endl;
}
if (broken) {
break;
}
}
use a boolean variable to state that you breaked from the inner loop and then check it and break from the outer loop if needed.
Try the following
bool done = false;
int i = 0;
for ( ; i < 100 && !done; i++ )
{
cout << "Enter Player Name (Q to quit): ";
getline(cin,playerName[i]);
if ( !( done = playerName[i] == "Q" || playerName[i] == "q" ) )
{
cout << "Enter score for " << playerName[i] << ": "<< endl << endl;
// some code for entering the score
}
}
Take into account that you need to keep variable i that to know how many players were entered. So I defined i outside the loop.