How to you make data validation go through? - c++

When testing my output, there's one part (the red circled part) that I'm having trouble with.
When the input starts with numbers and then letters, it goes through (ex. 45Gge). After, the program ends, skipping the part where it asks if they want to do it again.
When the input starts with letters and/or numbers, the validation fails loop works (ex. gsdf or ggs52). Does anyone know why it allows for numbers then letters to go through?
#include <iostream>
#include <iomanip>
#include <limits>
int main()
{
float fee = 0.0;
float hours = 0.0;
float minFee = 2.50;
char choice;
std::cout << std::setprecision(2) << std::fixed;
do
{
std::cout << "Enter parking hours: ";
std::cin >> hours;
while(std::cin.fail())
{
std::cout << "\nIncorrect Input! Numbers Only.\nTry Again.";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
std::cout << "\n\nEnter parking hours: ";
std::cin >> hours;
}
if(hours <= 3)
{
fee = minFee;
}
else if(hours > 3 && hours < 24)
{
fee = (((hours - 3) * 1) + minFee);
}
else
{
fee = 20.00;
}
std::cout << "\nTotal Cost: $" << fee;
std::cout << "\n\nWould you like to pay another fee? (Y or N): ";
std::cin >> choice;
while(choice != 'y' && choice != 'n')
{
std::cout << "\nIncorrect Input! \"Y\" or \"N\" Only.\nTry Again.";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
std::cout << "\n\nWould you like to pay another fee? (Y or N): ";
std::cin >> choice;
}
}while(choice == 'y');
std::cout << "\nThankyou for your payment." << std::endl;
return 0;
}
I want the circled part to validate the data.

Related

C++ Error: Continue option is not working and is looping the program instead

Note: I am a beginner in C++, so please bear with me if there are any serious programming errors that can be fixed easily.
Edit: Options 3 and 4 work perfectly fine without any errors. However, Option 2 has a serious looping problem where 'Error! Number should be in range of (1 to 100)' and 'Enter the number again:' loop continuously when you input any key. Will change the code to show the code for Option 2 and remove Option 3 and Option 4's code.
I created a math program that can calculate numbers, calculate fractions, among other features I added. I added a continue button on some programs (Option 2) that when you enter 'Y' on your keyboard, it should loop the program until the user types a different key to signify that the program should stop. However, the continue button seems not to work. When I press any other key, the program still loops and I have to stop the program so it cannot loop.
#include <<iostream>>
#include <<cmath>>
using namespace std;
int main()
{
std::cout << "Math Application Version 0.1 (currently in development)\n";
std::cout << "Choose an application to use (use numbers 1 - 10)\n":
std::cout << "Option 1: Calculator" << std::endl "Option 2: Use Average Calculator" <<
std::endl << "Option 3: Use Fraction Calculator\n" << std::endl <<
"Option 4: Use LCM (Lowest Common Denominator) Calculator\n";
int choice;
std::cin >> choice;
switch (choice)
{
case 1:
// this is blank on purpose because this would get too long if I added more features here
case 2:
{
printf("\n Chose average calculator.");
char d;
int n, i;
float num[100],
sum=0.0,
average;
anon:
{
cout << "Enter the numbers of data (limit is 100) : ";
cin >> n;
while (n > 100 || n <= 0)
{
cout << "Error! Number should be in range of (1 to 100)." << endl;
cout << "Enter the number again: ";
cin >> n;
}
for (i = 0; i < n; ++i)
{
cout << i + 1 << ". Enter number: ";
cin >> num[i];
sum += num[i];
}
average = sum / n;
cout << "Average = " << average;
}
cout << "\nDo you want to continue? "; cin >> n;
if (n== 'Y', "Yes")
goto anon;
system("PAUSE");
return 0;
break;
}
I'd appreciate any help on this issue or a detailed explanation since this is very confusing for me.
Your code is fine but you just have some typos in these lines.
cout << "\nDo you want to continue? ";
cin >> n;
/*Here => */ if (n== 'Y', "Yes")
fix it to if(n == 'Y'), also you have unintentionally used n instead of the char d that you have defined to use as a check.
So your code should be
cout << "\nDo you want to continue? ";
cin >> d;
if (d == 'Y') { .... }
And for completion, avoid goto whenever you can. You can use a while loop instead of the assembly-like goto.
This is your code but with a while loop instead of goto
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
std::cout << "Math Application Version 0.1 (currently in development)\n";
std::cout << "Choose an application to use (use numbers 1 - 10)\n";
std::cout << "Option 1: Calculator" << std::endl << "Option 2: Use Average Calculator" <<
std::endl << "Option 3: Use Fraction Calculator\n" << std::endl <<
"Option 4: Use LCM (Lowest Common Denominator) Calculator\n";
int choice;
std::cin >> choice;
switch (choice)
{
case 1:
// this is blank on purpose because this would get too long if I added more features here
case 2:
printf("\n Chose average calculator.");
char d = 'Y';
int n, i;
float num[100],
sum=0.0,
average;
while (d == 'Y'){
cout << "Enter the numbers of data (limit is 100) : ";
cin >> n;
while (n > 100 || n <= 0)
{
cout << "Error! Number should be in range of (1 to 100)." << endl;
cout << "Enter the number again: ";
cin >> n;
}
for (i = 0; i < n; ++i)
{
cout << i + 1 << ". Enter number: ";
cin >> num[i];
sum += num[i];
}
average = sum / n;
cout << "Average = " << average;
cout << "\nDo you want to continue? ";
cin >> d;
}
break;
}
}

Why am I getting Warning: C4244?

So I've been getting: Warning C4244 '=': conversion from 'double' to 'long', possible loss of data line 158. From what I understand is that 'pow' and 'long int result' are somehow connected to this, I have been messing around with it and changed 'long int result' to 'double result' and got rid of the warning. I have a solution to get rid of the warning, but it won't matter since this program need long int to handle more data otherwise it will overflow if I use double.
If I decided to keep this warning in the program will there be potenial issues with it?
Can I somehow get rid of the warning and still be able to use 'long int result' or at least be able to handle more data some other way?
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
char menu, choice;
int numberYears = 0;
long int deposit, withdraw;
long int result = 0;
long int annualDeposit = 0;
float interestRate = 0.0;
long int balance = 0;
cout << "------------------------------\n" << "Welcome to Bank Simulator 3000" << "\n------------------------------\n\n";
while (true)
{
cout << "XXXXXXX[MENU]XXXXXXXX\n";
cout << "[D]eposit\n";
cout << "[W]ithdrawal\n";
cout << "[B]alance\n";
cout << "[I]nterest payment\n";
cout << "[E]xit\n";
cout << "XXXXXXXXXXXXXXXXXXXXX\n";
cin >> menu;
switch (menu)
{
case'd':
case'D':
cout << "\n[DEPOSIT]\n";
cout << "Do you want to make a deposit?\n" << "Y/N\n";
cin >> choice;
if (choice == 'Y' || choice == 'y')
{
cout << "\nHow much do you want to deposit?\n" << "\n:";
}
else
{
cout << "\nReturning to menu.\n\n";
continue;
}
cin >> deposit;
balance += deposit;
cout << "\n" << deposit << " Kr has been added to balance.\n\n";
continue;
case'w':
case'W':
cout << "\n[WITHDRAWAL]\n" << "Do you want to make a withdrawal?\n" << "Y/N\n";
cin >> choice;
if (choice == 'Y' || choice == 'y')
{
cout << "\nHow much do you want to withdraw?\n" << "\n:";
}
else
{
cout << "\nReturning to menu.\n\n";
continue;
}
cin >> withdraw;
if (withdraw == 0)
{
cout << "\nYou withdrew 0 amount. No changes will apply.\n\n";
continue;
}
balance -= withdraw;
cout << "\n" << withdraw << " Kr has been drawn from balance.\n\n";
continue;
case'b':
case'B':
cout << "\n[BALANCE]\n";
cout << balance << " Kr\n\n";
continue;
case'i':
case'I':
cout << "\n[INTEREST PAYMENT]\n";
cout << "Do you want to calculate your interest payment?\n" << "Y/N\n";
cin >> choice;
if (choice == 'Y' || choice == 'y')
{
cout << "What's your annual deposit?\n" << ":";
}
else
{
cout << "\nReturning to menu.\n\n";
continue;
}
cin >> annualDeposit;
if (annualDeposit == 0)
{
cout << "You typed 0 in your annual deposits, this will give unwanted results.\n" << "Do you want to continue?\n" << "Y/N\n";
cin >> choice;
if (choice == 'Y' || choice == 'y');
else
{
cout << "Returning to menu.\n\n";
continue;
}
}
cout << "What's Your Interest Rate?\n" << ":";
cin >> interestRate;
if (interestRate == 0)
{
cout << "You typed 0 in your interest rate, this will give unwanted results.\n" << "Do you want to continue?\n" << "Y/N\n";
cin >> choice;
if (choice == 'Y' || choice == 'y');
else
{
cout << "Returning to menu.\n\n";
continue;
}
}
cout << "How many years do you want to save to?\n" << ":";
cin >> numberYears;
if (numberYears <= 0)
{
cout << "You typed 0 or less in number of years, this will give unwanted results.\n" << "Do you want to continue?\n" << "Y/N\n";
cin >> choice;
if (choice == 'Y' || choice == 'y');
else
{
cout << "Returning to menu.\n\n";
continue;
}
}
result = annualDeposit * pow(1 + interestRate / 100, numberYears);
cout << "Your Interest Payment Will Be: " << result << " Kr In " << numberYears << " Years\n\n";
continue;
default:
cout << "\nPlease use the following example\n" << "D = Deposit | W = Withdrawal | B = Balance | I = Interest payment | E = Exit\n\n";
continue;
case'e':
case'E':
cout << "Thanks for using Bank Simulator 3000!\n";
cout << "Press any key to close";
system("pause>0");
break;
}
break;
}
return(0);
}
In typical environment, a double variable can store a floating-point number upto about 10^300 (assuming IEEE754 64-bit is used).
On the other hand, a long int can store an integer only upto about 10^9 (32-bit) or 10^18 (64-bit).
Therefore, the maximum value to handle by long int is much smaller than one for double. This is why conversion from double to long int can cause loss of data.
You can add an explicit cast to suppress the warning.
result = static_cast<long int>(annualDeposit * pow(1 + interestRate / 100, numberYears));

C++ Program crashes/infinite looping if a letter is inputted as an answer instead of a number [duplicate]

Sorry if I fail to be clear enough or make any mistakes, this is my first time posting.
My code runs without errors when complied but the first while loop (in int main) gets stuck looping whenever a user types a letter (like "a") for cin >> select; instead of the required 1, 2, or 3.
However, when I input "4" or any other random string of numbers, it runs fine and goes to my error message like it should.
Why is this and what can I do to make it run normally? (run the error message in response to letters entered as if they were numbers).
My code:
#include <iostream>
#include <string>
using namespace std;
void calculator();
void unavailableitem();
int main()
{
string select;
while (true)
{
cout << "\t[Main Menu]\n";
cout << " 1. Calculator\n";
cout << " 2. [unavailable]\n";
cout << " 3. [unavailable]\n";
cout << "\n Enter the number of your selection: ";
cin >> select;
if (select == "1")
{
cout << endl;
calculator();
break;
}
else if (select == "2")
{
unavailableitem();
break;
}
else if (select == "3")
{
unavailableitem();
break;
}
else
cout << "\nInvalid response.\n";
}
}
void unavailableitem()
{
string react;
cout << "\n \t [ITEM UNAVAILABLE]\n";
while (true)
{
cout << "\nEnter 'menu' to return to main menu: ";
cin >> react;
if (react == "menu")
{
cout << endl;
main();
break;
}
else
cout << "\nInvalid response.\n";
}
}
void calculator()
{
int choice;
double num1;
double num2;
double answer;
string choicesymbol;
cout << "List of operations:\n";
cout << " 1. Addition\n";
cout << " 2. Subtraction\n";
cout << " 3. Multiplication\n";
cout << " 4. Division\n";
cout << "Enter the number on the left to pick an operation: ";
cin >> choice;
cout << "\nEnter number 1: ";
cin >> num1;
cout << "\nEnter number 2: ";
cin >> num2;
if (choice == 1)
{
answer = num1 + num2;
choicesymbol = " + ";
}
if (choice == 2)
{
answer = num1 - num2;
choicesymbol = " - ";
}
if (choice == 3)
{
answer = num1 * num2;
choicesymbol = " * ";
}
if (choice == 4)
{
answer = num1 / num2;
choicesymbol = " / ";
}
cout << endl;
cout << num1 << choicesymbol << num2 << " = " << answer;
}
New code:
#include <iostream>
#include <string>
using namespace std;
void calculator();
void unavailableitem();
int main()
{
int select;
while (true)
{
cout << "\t[Main Menu]\n";
cout << " 1. Calculator\n";
cout << " 2. [unavailable]\n";
cout << " 3. [unavailable]\n";
cout << "\n Enter the number of your selection: ";
cin >> select;
if(!(cin >> select))
{
cout << "Input must be an integer.\n";
cin.clear();
continue;
}
else if (select == 1)
{
cout << endl;
calculator();
break;
}
else if (select == 2)
{
unavailableitem();
break;
}
else if (select == 3)
{
unavailableitem();
break;
}
}
}
void unavailableitem()
{
string react;
cout << "\n \t [ITEM UNAVAILABLE]\n";
while (true)
{
cout << "\nEnter 'menu' to return to main menu: ";
cin >> react;
if (react == "menu")
{
cout << endl;
return;
break;
}
else
cout << "\nInvalid response.\n";
}
}
void calculator()
{
int choice;
double num1;
double num2;
double answer;
string choicesymbol;
cout << "List of operations:\n";
cout << " 1. Addition\n";
cout << " 2. Subtraction\n";
cout << " 3. Multiplication\n";
cout << " 4. Division\n";
cout << "Enter the number on the left to pick an operation: ";
cin >> choice;
cout << "\nEnter number 1: ";
cin >> num1;
cout << "\nEnter number 2: ";
cin >> num2;
if (choice == 1)
{
answer = num1 + num2;
choicesymbol = " + ";
}
if (choice == 2)
{
answer = num1 - num2;
choicesymbol = " - ";
}
if (choice == 3)
{
answer = num1 * num2;
choicesymbol = " * ";
}
if (choice == 4)
{
answer = num1 / num2;
choicesymbol = " / ";
}
cout << endl;
cout << num1 << choicesymbol << num2 << " = " << answer;
}
Ad Ed Heal mentioned, the issue here is cin's failbit. When you do cin >> choice, and the user types "a", then the conversion to int fails. This sets cin's failbit, making all future reads from it fail until the failbit is cleared. So the next time you reach cin >> choice, the user won't even get to type anything.
You can use cin.clear() to restore to working order.
To do this a bit more robustly, you could do something like
while(true)
{
cout >> "Enter choice [1-4]: ";
if(!(cin >> choice))
{
cout << "Input must be an integer.\n";
cin.clear();
continue;
}
do_stuff_with_choice();
}
I am a newbie to programming in general, but playing with your code and looking up stuff made me find some sort of solution.
The cin.clear only clears the error log of the input, and I believe that it still retains the value of the letter.
What you should add right after is a cin.ignore(#,'\n') (# being a very, very large number) to have it avoid the line and skip right through it.
Found the solution in another question that explains the use of both cin commands.

How to check user input?

SO I want to be able to invalidate all user input except a certain word, like 'K' or 'C'. I'm not sure at all how to do this. So if they mispell it to "celcius" or "husdhfjae", my program would say "Input invalid, please enter K or C."
Please nothing too complicated, because I just started. Thank you :)
// CS 575,HW #1B, Ravela Smyth
// This program converts from Fahrenheit to Celsius or Kelvin
#include <iostream>
#include <string>
using namespace std;
int main() {
string input;
double Fahrenheit, celsius, kelvin;
cout << "Hi! What is the weather today in Fahrenheit?? " << endl;
cin >> Fahrenheit;
cout << "Would you like to convert this temperature to Celsius or Kelvin? (C/K)" << endl;
cin >> input;
if (input == "C")
{
celsius = (5 * (Fahrenheit - 32)) / 9;
cout << "Today's weather in Celsius is " << celsius << " degrees! " << endl;
}
else if (input == "c")
{
celsius = (5 * (Fahrenheit - 32)) / 9;
cout << "Today's weather in Celsius is " << celsius << " degrees! " << endl;
}
else if (input == "K")
{
kelvin = (5 * (Fahrenheit + 459.67)) / 9;
cout << "Today's weather in Kelvin is " << kelvin << " degrees!" << endl;
}
else if (input == "k")
{
kelvin = (5 * (Fahrenheit + 459.67)) / 9;
cout << "Today's weather in Kelvin is " << kelvin << " degrees!" << endl;
}
return 0;
}
Usually user inputs are checked using while or do...while loops.
The idea is simple, you always get back to the same error message and read again the input until it is correct.
The advantage of placing the valid options in the single string is to allow easy addition or removal of the options without dealing with long if conditions.
I believe something simple like this will do the job:
std::string valid_options("kKcC");
std::string input;
bool illegal_input;
std::cout << "Would you like to convert this temperature to Celsius or Kelvin? (C/K)" << std::endl;
std::cin >> input;
// check that only one letter was provided and it belongs to the valid options
while (input.size() != 1 || valid_options.find(input) == std::string::npos)
{
std::cout << "Input invalid, please enter K or C.\n";
std::cin >> input;
}
First, you can do something like if(input == "C" || input == "c")
Or you can convert the input to lower/upper case
Second, you can add an else statement that says something like "please enter a valid command". Play around with it, you can even use loops to wait for correct input!
My approach is to test the input against a container of all valid inputs.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
bool valid(std::string s,std::vector<std::string> y)
{
std::sort(y.begin(), y.end());
return std::binary_search(y.begin(), y.end(), s);
}
int main()
{
std::string s;
do
{
std::cout << "Enter K or C: ";
std::cin >> s;
} while (!valid(s, { "K","C","k","c" }));
std::cout << "good!" << std::endl;
return 0;
}
You need a while loop. This is probably the simplest way to do it.
#include <iostream>
#include <string>
int main()
{
std::string word;
std::cin >> word;
//Keep asking for a word until this condition is false, i.e.
//word will be equal to one of these letters
while(word != "C" && word != "c" && word != "K" && word != "k")
{
std::cout << "Invalid temperature type: " << word << " Use 'K' or 'C'" << std::endl;
std::cin >> word;
}
if (word == "C" || word == "c")
{
std::cout << "Celsius" << std::endl;
}
else if (word == "K" || word == "k")
{
std::cout << "Kelvin" << std::endl;
}
}
I had the same problem while getting the correct user input for that i wrote a simple solution i hope it will be helpfull for everyone getting started with c++.
//get user input
char input;
cin >> input;
//convert the input to lowercase
char Temp = tolower(input);
//check the input (not valid input will clear the user input)
while(!(cin >> input) || ((Temp != 'c') &&( Temp != 'k')){
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input. Please, try again: ";
}
//evalute input cases
switch (Temp)
{
case 'c':
/* celcius */
break;
case 'k':
/* Kelvin */
break;
}

How do I incorporate input validation in this code?

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;
}