I have a quick question for input verification. I have my loop, and it works for negative numbers, but when I input something like a + sign, it causes an infinite loop. Is there any way to fix it?
cout << "Input Quarter 1 Sales: " << endl;
cin >> quarter1;
while (quarter1 < 0)
{
cout << "Error! Sales Must be a Positive Number!" << endl;
cout << "Please Input a Positive Number" << endl << endl;
cin >> quarter1;
}
Related
I am having difficulty locating and solving a bug in my basic ATM program. The issue manifests in the withdrawal option of both the checking and savings accounts. After the account has zero available funds it will allow the user to enter a negative number essentially over-drafting the account. I am trying to prevent this from happening.
Additionally, if there are zero funds available to withdraw the program continues to loop, thereby not allowing the user to utilize the menu to select a different option.
I have provided examples of the screen output illustrating the issues and the some of the source code.
Issue
Issue
#include <iomanip>
#include <iostream>
using std::cin;
using std::cout;
double checking_balance = 2500.00, savings_balance = 1000.00, savings_amount,
checking_amount;
int menu;
int main() {
do {
// Main Menu
cout << std::fixed << std::setprecision(2);
cout << "\n";
cout << "\tWelcome to Seabreeze Bank\n";
cout << "*********************************\n\n";
cout << "1. Savings Account\n";
cout << "2. Checking Account\n";
cout << "3. Quit\n\n";
cin >> menu;
cout << "\n\n";
// User validation for the Main Menu
if (menu < 1 || menu > 3) {
cout << "You have entered an invalid option.\n";
cout << "Please enter a number 1-3 > ";
cin >> menu;
cout << "\n\n";
}
switch (menu) {
case 1:
int savings_menu;
do {
// Savings Account Menu
cout << "\t\tSavings Account\n\n";
cout << "Please enter a menu item (1-3) >\n";
cout << "*********************************\n";
cout << "1. Withdrawal\n";
cout << "2. Deposit\n";
cout << "3. Main Menu\n";
cout << "\n\n";
cin >> savings_menu;
cout << "\n";
// Withdrawal selection for Savings Account
if (savings_menu == 1) {
cout << "How much would you like to withdraw from your savings "
"account: ";
cin >> savings_amount;
cout << "\n";
while (savings_balance < savings_amount) {
cout << "You do not have enough funds in your account to withdraw "
"that much\n";
cout << "Please enter a smaller amount: ";
cin >> savings_amount;
cout << "\n";
}
while (savings_amount <= 0) {
cout << "Please enter an amount greater than 0: ";
cin >> savings_amount;
}
savings_balance -= savings_amount;
cout << "Your Savings Account Balance: " << savings_balance << "\n\n";
if (savings_balance == 0) {
cout << "You now have zero funds in your Savings Account.\n\n";
}
}
This is a floating point arithmetic problem.
In general, floating point arithmetic is not exact because of rounding errors, saving_amount is not equal to 0 but it is almost equal to 0.
I prefer the casting option because in certain cases using the round() function will need a bit more modification if the result is negative.
Instead of "while (savings_amount <= 0)" you should use while (int(saving_amount) <= 0). Similarly you have to do casting where you are using conditional operator in your program.
To prevent entering negative number to withdraw, you have to put an "if" statement to check if number is negative.
I already posted this question, but none of the responses were correct once I implemented the suggestions I was given. Here is what I need to happen.
Would you like to process all the records in the file? (y/n) w
Error - Please enter either y or n.
Would you like to process all the records in the file? (y/n) n
Enter number of records to process: two
XXXXXXXXXX Error-non numeric or negative value, try again
Enter number of records to process: -10
XXXXXXXXXX Error-non numeric or negative value, try again
Enter number of records to process: 0
XXXXXXXXXX Error-non numeric or negative value, try again
Enter number of records to process: 10
Maximum requested record count of 10 reached
Here is what I have. I don't know what I am doing wrong.
#include <iostream>
#include <fstream>
using namespace std;
int main(){
char a = 0; //User chooses Y or N
int ProcessAmount = 0; //Amount of times to process if not all
cout << "Would you like to process all the records in the file? "
<< "(y/n) ";
cin >> a;
if (a == 'y')
{
cout << "Processed all records successfuly" << endl;
}
do
{
if (a == 'n')
{
cout << "Enter number of records to process: ";
cin >> ProcessAmount;
if (ProcessAmount <= 0 or cin.fail())
{
cout << "" << endl;
cout << "XXXXXXXXX Error-non numeric or negative value";
cout << "" << endl;
cin >> ProcessAmount;
}
else if (ProcessAmount >= 0 or (!(cin.fail())))
;
{
cout << "Maximum requested record count of " << ProcessAmount;
cout << " reached" << endl;
break;
}
}
else
(cin.fail());
{
cin.clear();
cin.ignore(40, '\n');
cout << "Please try again" << endl;
cout << "Would you like to process all the records in the file? "
<< "(y/n) ";
cin >> a;
}
} while (a == 'n');
}
First of all or is something I didn't know worked in C++, but in my gcc compiler it works fine, so thank you for that, I still replaced it with || in my answer, though.
Apart from that there are some issues with the sequence of events in your do - while cycle, try the code below.
Live sample here
do {
if (a == 'y') {
cout << "Processed all records successfuly" << endl;
break;
}
if (a == 'n') {
cout << "Enter number of records to process: ";
cin >> ProcessAmount;
if (ProcessAmount <= 0 || cin.fail()) {
cout << "XXXXXXXXX Error-non numeric or negative value";
cout << "" << endl;
}
else {
cout << "Maximum requested record count of " << ProcessAmount;
cout << " reached" << endl;
break;
}
cin.clear();
cin.ignore(40, '\n');
continue;
}
cout << "Please try again" << endl;
cout << "Would you like to process all the records in the file? "
<< "(y/n) ";
cin >> a;
} while (a != 'y');
First of all, the value of a must be validated, with something like:
cout << "Would you like to process all the records in the file? "
<< "(y/n) ";
cin >> a;
//validating a
while (a != 'n' && a != 'y'){
cout << "Error - Please enter either y or n." << endl;
cout << "Would you like to process all the records in the file? "
<< "(y/n) ";
cin >> a;
}
//...do things if a='n'
//...do thing if a='y'
then you should stop worrying about a, then you can do things if a = n or if a = y
I am prompting the user to enter an integer value. When the value is incorrect, the program works. However, when the user enters an integer input, the user needs to enter the input twice.
I looked at other tutorials on how to use the while loop to catch erroneous input, and that part worked for me. However, the integer values need to be entered twice in order for the program to run.
#include <iostream>
using namespace std;
int main() {
cout << "*************************************************" << endl;
cout << "******************|DVD Library|******************" << endl;
cout << "*************************************************" << endl;
cout << "1.\tAdd DVD" << endl;
cout << "2.\tDelete DVD" << endl;
cout << "3.\tSearch DVD" << endl;
cout << "4.\tList All DVDs in the Library" << endl;
cout << "5.\tAdd DVD to Favorites List" << endl;
cout << "6.\tDelete DVD from Favorites List" << endl;
cout << "7.\tSearch DVD in Favorites List" << endl;
cout << "8.\tList All DVDs in Favorites List" << endl;
cout << "9.\tQuit" << endl;
cout << "*************************************************" << endl;
int input;
cin >> input;
while (!(cin >> input)) {
cin.clear();
while (cin.get() != '\n')
continue;
cout << "Please enter an integer --> " << flush;
}
if (input < 1 || input > 9) {
cout << "Invalid input! Please try again!" << endl;
}
return 0;
}
You ask for the input twice:
cin >> input;
while(!(cin >> input )){
Removing the first line might make it work you intended.
'The user has to enter the input twice' Look at your code
int input;
cin >> input;
while(!(cin >> input )){
How many times do you ask the user for input?
You'd have more luck with this
int input;
while(!(cin >> input )){
Your error recovery code looks reasonable, haven't tested it though.
int input;
while (cout << "Your choice: ",
!(cin >> input) || input < 1 || 9 < input)
{
cin.clear();
while (cin.get() != '\n');
cerr << "Invalid input! Please try again!\n";
}
Thanks everyone! The "cin >> input;" line was unnecessary. At first, I left it there because it would actually tell the user the error message if the user entered a numeric input such as a double. So, if the user entered something like 3.3, the program would display an error message that I specified ("Please enter an integer" line). However, the program in this case (when there is a double) asks the user to prompt for the integer input twice and then continues the program. When I delete the said unnecessary line, the program accepts a double input, but what it does, it takes the numeric value before the decimal point and uses it as the integer. So, a value of 1.2 is recorded as 1 when I tested it. I'm unsure why this phenomenon happens, but the program works otherwise. Maybe it accounts for human error?
#include <iostream>
using namespace std;
int main() {
cout << "*************************************************" << endl;
cout << "******************|DVD Library|******************" << endl;
cout << "*************************************************" << endl;
cout << "1.\tAdd DVD" << endl;
cout << "2.\tDelete DVD" << endl;
cout << "3.\tSearch DVD" << endl;
cout << "4.\tList All DVDs in the Library" << endl;
cout << "5.\tAdd DVD to Favorites List" << endl;
cout << "6.\tDelete DVD from Favorites List" << endl;
cout << "7.\tSearch DVD in Favorites List" << endl;
cout << "8.\tList All DVDs in Favorites List" << endl;
cout << "9.\tQuit" << endl;
cout << "*************************************************" << endl;
int input;
while (!(cin >> input)) {
cin.clear();
while (cin.get() != '\n')
continue;
cout << "Please enter an integer --> " << flush;
}
if (input < 1 || input > 9) {
cout << "Invalid input! Please try again!" << endl;
}
return 0;
}
My program runs the first For loop correctly then skips the Cin's on the 2nd and 3rd cycle. Then when the loop is finished it goes on to calculate the BMI of the first index [0] and does this correctly and gives the right answer but then nothing for the index's 1 and [2] because no information was inputted because the cin's were skipped.
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
struct Patient
{
double height;
double weight;
int age;
bool isMale;
};
int main()
{
Patient Patients[3];
for (int i = 0; i < 3; i++) {
cout << "Patient "<< i << " Height: ";
cin >> Patients[i].height;
cout << "Patient " << i << " Weight: ";
cin >> Patients[i].weight;
cout << "Patient " << i << " Age: ";
cin >> Patients[i].age;
cout << "Is Patient " << i << " Male True or False: ";
cin >> Patients[i].isMale;
cout << endl << endl;
}
cout << endl << endl;
for (int i = 0; i < 3; i++) {
float BMI = Patients[i].weight / (Patients[i].height *Patients[i].height);
cout << "Patient " << i << " Has A BMI of: " << BMI << endl << endl;
}
return 0;
}
This is the console where you can see after the first loop all the cin's are skipped but the first loop was correctly stored as it couted the BMI of the first index:
You see that you are having an error at the end of the loop. You can see from iterations 2 and 3 that cin is not behaving the same way each time. There are a couple of error state flags that come from ios that will help you see what's going wrong here. See iso::good for details. If you add those checks:
for (int i = 0; i < 3; i++) {
cout << "Patient " << i << " Height: ";
cin >> Patients[i].height;
cout << "Patient " << i << " Weight: ";
cin >> Patients[i].weight;
cout << "Patient " << i << " Age: ";
cin >> Patients[i].age;
cout << "Is Patient " << i << " Male True or False: ";
cin >> Patients[i].isMale;
cout << cin.good() << '\n';
cout << cin.eof() << '\n';
cout << cin.fail() << '\n';
cout << cin.bad() << '\n';
cout << endl << endl;
}
What you will see if that cin is no longer good, it is not eof it is fail, and it is not bad. While the fail bit is set, cin will not work. Hence you see the result. Looking at the chart in the link you see this:
Logical error on i/o operation
You were preforming an i/o operation of inserting "true" into a bool. The word true is probably stored as a character array or string, not a boolean. How should cin convert this to a boolean? You need to trap your input and convert it into a bool or switch to use an input that can be explicitly converted into a bool.
For example:
cout << "Is Patient " << i << " Male? (1 for Male, 0 for Female):";
cin >> Patients[i].isMale;
In this case the cin recognizes 1 and 0 as integers and can convert an integer into a boolean. 0 is false, everything else is true. Another option is to let the library do it and use boolalpha. You can read about it here.
This shows a larger issue. What happens if I write "two point five" as the answer to height? In this case we can assume some intelligence on the part of the user, but thinking about things like this will help write more robust code in the future.
You can fix your program in two ways.
Just input "0" or "1" in the male/female question instead of "true" or "false".
Change this line and continue to input "true" or "false":
cin >> boolalpha >> Patients[i].isMale;
Sources:
Cin and Boolean input
http://www.cplusplus.com/reference/ios/boolalpha/
I am trying to implement input validation into this program but it keeps coming out wrong. I tried using another while statement but it didn't work. It normally pops up with the text which shouldn't be. I want it to show after the person inputs the wrong information. I want it so that if the data entered is invalid, they will have to re enter it.
Here is the code I have so far.
/*
1. Declare variables for month 1, 2, and 3.
2. Declare variable for Total and Average Rainfall
3. Ask user to input name of months.
4. Then ask user to input inches of rain fall.
5. Add all inches and then divide by number of inches asked. In this case, 3.
6. Display average inches of rain for all months to user.
*/
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
string month1, month2, month3;//Declared values for months aswell as total and average rainfall.
double month1Inch, month2Inch, month3Inch;
double averageInches;
double totalInches;
char c = 'y';
do
{
cout << setprecision(2) << fixed;
cout << "Enter first month's name:";
cin >> month1;
cout << "Enter rain inches for " << month1 << ":";
cin >> month1Inch;
cout << "\n";
cout << "Enter second month's name:";
cin >> month2;
cout << "Enter rain inches for " << month2 << ":";
cin >> month2Inch;
cout << "\n";
cout << "Enter third month's name:";
cin >> month3;
cout << "Enter rain inches for " << month3 << ":";
cin >> month3Inch;
cout << "\n";
totalInches = (month1Inch + month2Inch + month3Inch);
averageInches = (totalInches) / 3;//calculating the average
//Display calculated data.
cout << "The average rainfall for " << month1 << ", " << month2 << ", " << "and " << month3 << " is " << averageInches << endl;
cout << "Would you like to recalculate? Either enter Y to run or N to not." << endl;
cin >> c;
} while (c == 'Y'||c=='y');
if (c != 'Y' || c != 'y')
cout << "you must enter the correct choice" << endl;
system("pause");
return 0;
}
I tried putting an if statement under "cout << "Would you like to recalculate? Either enter Y to run or N to not." << endl;
cin >> c;" but i get an infinite loops.
I am not getting any error codes. Just the text showing up with "would you like to recalculate?" line and infinite loops.
Even when I input the data with that showing, I get an infinite loop somewhere. So I deleted it.
It sounds like you want to validate the Yes or No response. That requires a loop that exits only when you have an acceptable input. It's separate from the loop that decides if the calculation should be run again.
int main() {
// ...
do {
// ...
do {
cout << "Would you like to recalculate? Either enter Y to run or N to not." << endl;
cin >> c;
} while (c != 'Y' && c != 'y' && c != 'N' && c != 'n');
} while (c == 'Y'|| c=='y');
system("pause");
return 0;
}