input validation and overflow in c++ - c++

I'm writing a code that takes a user's input and calculates a discount based on how many units the user buys. Here is my problem; I want to use input validation to make sure the number entered is between 0 and 65535 (the max range for an unsigned int) but the way I have this program set up, if the user enters a number outside of this range I'm experiencing overflow/underflow and an incorrect number is stored in the variable before it ever even hits the if/else clauses. I'm new to C++ so please be kind. What can I do to check if this number is in the correct range when the user enters it. Also, is there a way to verify that the user has not entered a character other than a number?
Here is my code:
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
// display the instructions and inform the user of the discounts available
cout << " This software package sells for $99. Discounts are given according to the following list: \n";
cout << "----------------------------------" << endl;
cout << " Quantity\t\t Discount" << endl;
cout << "----------------------------------" << endl;
cout << " 10 - 19\t\t 20%" << endl;
cout << " 20 - 49\t\t 30%" << endl;
cout << " 50 - 99\t\t 40%" << endl;
cout << " 100 or more\t\t 50%" << endl;
cout << "----------------------------------" << endl;
cout << "\n\n";
const double price = 99.00;
unsigned short quantity; // variable to hold the user's quantity.
// shouldn't need more than 2 bytes for this (unsigned short)
cout << "How many units are sold?: ";
cin >> quantity;
double discount; // variable to hold the amount discounted
double total; // to hold the total sales price
cout << fixed << showpoint << setprecision(2); // set the display of numeric values
// calculate the discounted prices
if (quantity >= 1 && quantity <= 9) {
total = quantity * price; // calculate the total without a discount
cout << "There is no discount for this order \n";
cout << quantity << " units were sold at $" << price << " a piece for a total of " << total << endl;
cout << "\n";
}
else if (quantity >= 10 && quantity <= 19) {
discount = (quantity * price) * .20; // calculate the discount
total = (quantity * price) - discount; // calculate the total
cout << "There is a 20% discount \n";
cout << quantity << " units were sold at $" << price << " with a discount of 20% applied to the order. \n";
cout << "The total cost of the sale is $" << total << endl;
cout << "\n";
}
else if (quantity >= 20 && quantity <= 49) {
discount = (quantity * price) * .30; // calculate the discount
total = (quantity * price) - discount; // calculate the total
cout << "There is a 30% discount \n";
cout << quantity << " units were sold at $" << price << " with a discount of 30% applied to the order. \n";
cout << "The total cost of the sale is $" << total << endl;
cout << "\n";
}
else if (quantity >= 50 && quantity <= 99) {
discount = (quantity * price) * .40; // calculate the discount
total = (quantity * price) - discount; // calculate the total
cout << "There is a 40% discount \n";
cout << quantity << " units were sold at $" << price << " with a discount of 40% applied to the order. \n";
cout << "The total cost of the sale is $" << total << endl;
cout << "\n";
}
else if(quantity > 99 && quantity <= 65535) {
// the maximum number allowed in a short int is 65535. I is unrealistic that someone would order more
// units than that so this else if clause checks to make sure the number of ordered items is below this number
discount = (quantity * price) * .50; // calculate the discount
total = (quantity * price) - discount; // calculate the total
cout << "There is a 50% discount \n";
cout << quantity << " units were sold at $" << price << " with a discount of 50% applied to the order. \n";
cout << "The total cost of the sale is $" << total << endl;
cout << "\n";
}
else {
// the trailing else clause is used to catch any value for quantity that is 0 or below or any quantity
// bigger than what a short int can hold.
cout << "You entered an invalid quantity.\n";
cout << "Please enter a value greater than 0 or less than 65,535. \n\n";
}
system("pause");
return 0;
}
The final else clause is only executed when a value of 0 is entered. Here is an example of the output with a value outside the range
This software package sells for $99. Discounts are given according to the following list:
----------------------------------
Quantity Discount
----------------------------------
10 - 19 20%
20 - 49 30%
50 - 99 40%
100 or more 50%
----------------------------------
How many units are sold?: 65600
There is a 50% discount
52428 units were sold at $99.00 with a discount of 50% applied to the order.
The total cost of the sale is $2595186.00
Press any key to continue . . .

So in all honesty, I don't think this is a bad question.
It just deals with error checking whatever comes out of cin >> quantity.
Like described here: User Input of Integers - Error Handling, a way to handle this is to wrap the cin >> quantity with some error handling code like below.
if (cin >> quantity) {
// read succeeded
} else if (cin.bad()) {
// IO error
} else if (cin.eof()) {
// EOF reached (perhaps combined with a format problem)
} else {
// format problem
}
This will not take care of the integer overflows however, so a full solution would be to make quantity an int and use
cout << "How many units are sold?: ";
if (cin >> quantity) {
// read succeeded
// check for range
if (quantity < 0 || quantity > 65535) {
cout << "Number needs to be between 0 and 65535" << endl;
return -1;
}
} else if (cin.bad()) {
// IO error
cout << "Couldn't do a read from stdin :(" << endl;
return -1;
} else if (cin.eof()) {
// EOF reached (perhaps combined with a format problem)
cout << "Stdin gave EOF :(" << endl;
return -1;
} else {
// format problem
cout << "Encountered incorrect format" << endl;
return -1;
}

Related

How to fix the calculation of tax yearly in a loop?

I need to write a program records membership fees for a Gym. The Gym charges a $1,200 per year, base fee but charges a percentage rate increase each year based on your membership rating:
Gold Members 1% fee
Silver Members 2% fee
Bronze Members 4% fee
It will display the following menu:
Welcome to Ronda’s Strikeforce Gym!!
x---------------------------------------------------x
Membership Fee Calculator
Gold
Silver
Bronze
Quit
Please enter your membership level (1-3 Enter 4 to Quit) >
The Validate input for the menu items listed, if 1 through 3 is entered, the program will use a loop to output the member's expected fees for the next 10 years. The output format is a table with the corresponding year and membership fee.
The program should continue to loop until the user is ready to quit. I am supposed to encapsulate the code in a do-while loop.
If a 4 is entered then the program should quit. Any other input should show an error message as output.
My output is not starting at the basevalue of 1200 but factors in the percentage. Upon another iteration of the program the last value calculated is used as a starting point.
This is what I have:
//Assignment 4-A.cpp: The program will calculate the membership fees over the next 10 years based on the membership level
#include <iostream>
#include <iomanip>
using namespace std;
int main() // Driver program
{
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);
//To hold menu choice
const int GOLD = 1,
SILVER = 2,
BRONZE = 3,
QUIT = 4;
//To hold the percentage tax of the different gym choices
const double tax_gold = .01,
tax_silver = .02,
tax_bronze = .04;
//To hold the base charge per year
const double base_charge = 1200.00;
//variables
double fees = 0, cost = base_charge, cost_1 = 1200.00;
//To hold the users input
int user_input;
const int min_number = 1,
max_number = 10;
int i;
do
{
cout << "\t Welcome to Ronda's Strikeforce Gym!!" << endl; //Title
cout << "x";
for (int i = 0; i <= 50; i++) //Dashed line, row
{
cout << ("-");
}
cout << "x";
cout << endl;
cout << "\t Membership Fee Calculation" << endl; //Title
//Display of gym membership plan choice
cout << "1. Gold" << endl;
cout << "2. Silver" << endl;
cout << "3. Bronze" << endl;
cout << "4. Quit" << endl << "\n";
cout << "Please enter your membership level (1-3 Enter 4 to Quit) ";
cin >> user_input;
cout << endl;
// Validate user input(must input 1 through 4), loop if value is invalid
while (user_input < 1 || user_input > 4)
{
cout << "Invalid entry! ";
cout << "Please enter a selection from 1 through 4: ";
cin >> user_input;
cout << endl;
}
// If values 1 - 3 were entered perform calculations else if 4 was entered exit program with thank you message.
// Perform calculation for specified membership for 10 years and output
if (user_input == 4)
{
break;
}
if (user_input != QUIT)
{
//Start selection loop and calculation
switch (user_input)
{
case 1:
fees = base_charge * tax_gold;
cost = base_charge + fees;
break;
case 2:
fees = base_charge * tax_silver;
cost = base_charge + fees;
break;
case 3:
fees = base_charge * tax_bronze;
cost = base_charge + fees;
break;
}
//Display Yearly Cost
for (int years = 1; years <= 10; ++years)
{
cout << "Year " << years << "\t $" << (cost_1 += fees) << endl;
}
cout << "\n";
}
} while (user_input != QUIT);
{
cout << "Thank you for using Ronda's Fee Calculator! \n";
}
cout << endl;
cout << "Press any key to continue . . .";
return 0;
}
This is what shows on my computer:
enter image description here
and this is what it should look like:
enter image description here
Thank you
Your calculations should start with the base rate (cost = 1200). For each year, print the current rate then add rate * tax. (cost += cost * tax).
Here's your code with a few modifications:
//To hold menu choice
const int GOLD = 1, SILVER = 2, BRONZE = 3, QUIT = 4;
//To hold the percentage tax of the different gym choices
const std::array<double, 3> tax_rates{.01, .02, .04};
//To hold the base charge per year
const double base_charge = 1200.00;
while (true) {
cout << "\t Welcome to Ronda's Strikeforce Gym!!\nx"; //Title
for (int i = 0; i <= 50; i++) //Dashed line, row
{
cout << ("-");
}
cout << "x\n\t Membership Fee Calculation\n"; //Title
//Display of gym membership plan choice
cout << "1. Gold" << endl;
cout << "2. Silver" << endl;
cout << "3. Bronze" << endl;
cout << "4. Quit" << endl << "\n";
cout << "Please enter your membership level (1-3 Enter 4 to Quit) ";
int user_input;
cin >> user_input;
cout << endl;
// Validate user input(must input 1 through 4), loop if value is invalid
while (user_input < 1 || user_input > 4)
{
cout << "Invalid entry! ";
cout << "Please enter a selection from 1 through 4: ";
cin >> user_input;
cout << endl;
}
// If values 1 - 3 were entered perform calculations else if 4 was entered exit program with thank you message.
// Perform calculation for specified membership for 10 years and output
if (user_input == QUIT)
{
break;
}
//Display Yearly Cost
double cost = base_charge;
for (int years = 1; years <= 10; ++years)
{
cout << "Year " << years << "\t $" << cost << endl;
cost += cost * tax_rates[user_input-1];
}
cout << "\n";
}
cout << "Thank you for using Ronda's Fee Calculator!\n\nPress any key to continue . . .";
Side note: it is recommended that you don't use floating point values for currency. FP can introduce rounding errors. You can use integers in the base denomination of the currency. In US dollars that would be cents (pennies). Just something to note for future projects.

C++ code for CS162 class isn't adding user inputs to the total

This code is designed to take an order, add that to the total_price variable, apply discounts based on the total price, then add a tip and echo all the information back to the user.
For some reason when I run the code, it isn't taking input from the user. I think it's related to the while statement but it outputs that my total_price is 0 after entering integers.
The tip calculation at the bottom isn't working correctly. It prompts the user to enter a tip value, but then skips to the end and says the final total is 0, without the user being able to enter any tip.
Thanks so much for the help!!
#include <iostream>
using namespace std;
int main()
{
int total_price{0}; // This variable will contain the price for all orders
int tip{0};
int discount_total{0};
int tip_total = tip + discount_total;
cout << "Welcome!\nThis program is designed to help take your order.\n";
cout << "Our discounts availible today are: \n10 percent off orders over $50, and 5 percent off orders between $25 and $50.\n";
// This is where the user is prompted to enter the price of their order
cout << "Please enter the price of your item: ";
cin >> total_price;
// No negative numbers will be accepted
if (total_price <= 0)
{
cout << "Invalid number, please re-enter the price of your item: ";
}
// User can continue ordering unless typing No
while (total_price > 0)
{
cout << "Is there anything else? If not type No: ";
cin >> total_price;
}
// Once the user types No, it brings them to the tip section
// Marks the end of the order
if ("No")
{
cout << "Thank you. Your total price is " << total_price << endl;
}
// Discount modifications
if (total_price >= 50)
{
discount_total = total_price * .05;
cout << "Your new total is " << discount_total << " with the 10 percent discount.\n";
}
else if (total_price >= 25 && total_price <= 50)
{
discount_total = total_price * .05;
cout << "Your new total is " << total_price << " with the 5 percent discount.\n";
}
else
{
total_price = discount_total;
cout << "Your total is the same, " << total_price << "\n";
}
// Tip calculation
cout << " Feel free to add a tip! Please enter here: ";
cin >> tip;
if (tip > 0)
{
cout << "Your final total is: " << tip_total << " dollars";
}
else if (tip < 0)
{
cout << "Your tip is invalid, please enter a valid tip: ";
}
return 0;
}

Telephone Bill Project: C++

Alright, I have edited some of the code, so now the question is how it calculates the right final total? I am working on the regular service, and I want it to subtract the 50 free minutes first, then add the extra minutes the user has overused, then multiply the extra minutes by $0.20 and make that into the finaltotal.
And if I have any more mistakes please tell me. I know I have made a lot of mistakes, sorry!
I have a project to do, and here is the requested functionalities list:
Prompts the user to enter an account number, a service code, and the number of minutes the service was used.
Regular: Values are “R” and “r”:
$10.00/month
First 50 min. are free
Charges for over 50 min. are $0.20 per min.
Premium: Values are “P” and “p”:
$25.00/month plus:
Calls between 6 - 18 first 75 min are free, after that they’re $0.10 per min
Calls between 18 - 6 first 100 min are free, after that they’re $0.05 per min
If any other character is used then display an error message
Calculate the total and print the bill (display it out)
This is my code:
#include <iostream>
using namespace std;
int main()
{
// VARIABLES //
int accnum, minnum, minnumm;
double total, finaltotal, grandtotal, finaltotall;
char scode;
cout << "Hello, thank you for paying your phone bill." << ends;
cout << endl;
cout << endl;
cout << "Please enter your account number: ";
cin >> accnum ; //Enter some number
cout << "Please enter your service code (r as regular service or p for premium service): ";
cin >> scode ; //Enter R or r for regular service and P or p for premium service
////////////// THIS IS FOR REGULAR SERVICE //////////////
if (scode == 'R' || scode == 'r') { // Values for Regular service
cout << "This service provides 50 minutes for phone calls for 50 minutes for free for $10.00 a month, and charge $0.20 every minute over 50 minutes." << endl;
cout << "How many minutes have you used up?: ";
cin >> minnum;
if (minnum > 50) {
total = minnum * .20;
finaltotal = total + 10;
cout << "You have made phone calls over 50 minutes, your total will be " << finaltotal << "." << endl;
cout << "Your account number is " << accnum << " , with a Regular service. You have used " << minnum << "/50 minutes. Your total is $" << finaltotal << " . Thank you for your time." << endl; //Displays the acc. #, type of service, # of min the phone service used, and amount due from user
cout << endl;
} else {
cout << "You have not made phone calls over 50 minutes, your total will be $" << finaltotal << "." << endl;
cout << "Your account number is " << accnum << " , with a Regular service. You have used " << minnum << "/50 minutes. Your total is $" << finaltotal << " . Thank you for your time." << endl; //Displays the acc. #, type of service, # of min the phone service used, and amount due from user
}
////////////// THIS IS FOR PREMIUM SERVICE //////////////
} else if (scode == 'P' || scode == 'p') { //Values for Premium service
cout << "This service provides your first 75 minutes phone calls from 6:00 - 18:00, and charge $0.10 for every minute over. Your first 100 minutes for phone calls from 18:00 - 6:00 are free, and charge $0.05 for every minute over." << endl;
cout << "How many minutes have you used up between 6:00 - 18:00? "; //Time between 6am - 6pm
cin >> minnumm;
if (minnumm > 75) { //If # of minutes is over 75
total = minnumm * .10; //Then it multiplies total * $.10
finaltotall = total + 25; //Then adds the $10/month
cout << "You have made phone calls over 75 minutes, your total will be $" << finaltotall << "." << endl;
} else {
cout << "How many minutes have you used up between 18:00 - 6:00? "; } //Time between 6pm - 6am
cin >> minnum;
if (minnum > 100) { //If # of minutes is over 100
total = minnum * .05; //Then it multiplies total * $.05
finaltotal = total + 25;
//Then adds the $25/month
cout << "You have made phone calls over 100 minutes, your total will be $" << finaltotal << "." << endl;
grandtotal = finaltotall + finaltotal; //Calculates both the 6am-6pm and 6pm-6am totals together
cout << "Your account number is " << accnum << " , with a Premium service. You have used " << minnumm << "/75 minutes from 6:00-18:00. You have used" << minnum << "/100 from 18:00-6:00. Your total is $" << grandtotal << " . Thank you for your time." << endl; //Displays the acc. #, type of service, # of min the phone service used, and amount due from user
} else {
cout << "You have not made phone calls over 100 minutes, your total will be $" << finaltotal << "." << endl;
cout << "Your account number is " << accnum << " , with a Premium service. You have used " << minnumm << "/75 minutes from 6:00-18:00. You have used " << minnum << "/100 from 18:00-6:00. Your total is " << grandtotal << " . Thank you for your time." << endl;
cout << endl;
cout << endl; } //Displays the acc. #, type of service, # of min the phone service used, and amount due from user
////////////// THIS IS IF THEY TYPED IN ANY LETTER OTHER THAN R, r, P, p //////////////
} else { //If user doesn't type P or R, then this is error message
cout << "Sorry, that service does not exist. Please try again." << endl;
cout << endl; }
system("pause");
return 0;
}
As far as I can see (and people in follow-up answers might find more errors), the glaring issue is that you have used the AND operator instead of the OR operator.
This statement:
if (scode == 'R' && scode == 'r') { // Values for Regular service
Should be:
if (scode == 'R' || scode == 'r') { // Values for Regular service
Similarly, this statement:
if (scode == 'P' && scode == 'p') { //Values for Premium service
Should be:
if (scode == 'P' || scode == 'p') { //Values for Premium service
A variable can't match two different values at the same time, so the if blocks will never be entered when using && instead of ||.

Can't get an int to update outside of the while loop

When it runs the winnings or losses are taken or added from the bank and then it is run again the bank is set back to a 25$ bank not the updated bank
int main()
{
srand(time(0));
int bank = 25;
int total;
char answer;
cout << "Come play Spin the Wheel. The wheel has numbers from 1-10." << endl
<< "If you spin an even number you lose that amount. If you spin" << endl
<< "an odd number you win that amount. You start with a 25$ bank." << endl;
cout << "Your bank is $" << bank << ". Would you like to spin the wheel? (y/n):" << endl;
cin >> answer;
while (toupper(answer) == 'Y')
{
int num = rand() % 10 + 1;
if (bank <= 10)
{
cout << "Sorry you must have more than 10$ to play" << endl;
}
else if (num % 2 == 0 )
{
total = bank + num;
cout << "You spun a " << num << " and won $" << num << endl;
cout << "Your bank is now: $" << total << endl;
}
else
{
total = bank - num;
cout << "You spun a " << num << " and lost $" << num << endl;
cout << "Your bank is now: $" << total << endl;
}
cout << "Would you like to play Again (y/n) ?" << endl;
cin >> answer;
}
return 0;
}
When it runs the winnings or losses are taken or added from the bank and then it is run again the bank is set back to a 25$ bank not the updated bank
You initialize bank to be 25 dollar in this function. Inside the while loop only total is updated not bank.
Another problem arises when there is too few money to play. I suppose you would like to display your message one time, but you are stuck inside the loop because it is never broken out of.
I believe your else if and else statements are backwards.
num % 2 == 0
Would signify that the number was even, if true. The instructions say that you lose the money if the number is even.
Bank will never be less than or equal to 10 because you are never setting bank to anything after the initial 25. Its always 25.
The variable total seems redundant. Maybe add or subtract the amount rolled directly from bank.
You need to set
bank = total
else you never change its value

Adding not multiplying

I am teaching myself C++, starting on the basics have written this:
// stringstreams
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main()
{
string mystr;
int price = 0;
int quantity = 0;
int total = price * quantity;
cout << "------------------------------------------------------" << '/n';
cout << "-----------------Welcome to the shop!-----------------" << '/n';
cout << "------------------------------------------------------" << '/n';
cout << "Enter price of item" << '/n';
getline(cin, mystr);
stringstream(mystr) >> price;
cout << "How Many do you want?" << '/n';
getline(cin, mystr);
stringstream(mystr) >> quantity;
cout << "you want this many: " << quantity << '/n';
cout << "at this price: " << price << '/n';
cout << "this would cost you: " << total << " pounds" << '/n';
if (total >= 20)
{
cout << "here is a discount of " << total / 20 << '/n';
}
else if (total >= 10)
{
cout << "here is a discount of " << total / 10 << '/n';
}
else
{
cout << "sorry no discount" << '/n';
};
}
My only problem is - its adding the total price instead of multiplying. I feel I am missing something very obvious but after an hour I cant seem to find out what it is, I have tried declaring total further down the code which has not worked, I have also tried putting the total in brackets still nothing.
What am I missing?
-- as an example --
10 units at the cost of 10 each, should come out at 100, not 20 as it does on my code
It's not doing anything with the total price, since it'll always be 0.
int total = price * quantity;
The result of the multiplication is performed and "saved" at this point, and doesn't change later even if price and quantity do.
You should put this line after the lines where you truly set the values of price and quantity.
As for your question about "adding not multiplying", with the fix in place as above the value output is correct, so you must be doing something wrong that we can't see. Check that you're running this code, and not some other piece of code.
Also, you've consistently written /n, whereas it should be \n (which further suggests that your screenshot is not from running this code). In fact, the two before your prompt for input should be endl, to ensure that the prompt is flushed to the console.
you are calculating the total at the wrong place.
Initially, you calculate total = price * quantity, with price = 0 and quantity = 0, and this will assign 0 to total. Then after inputting the quantity and price, you do not recalculate the total, so it gives you the wrong result.
My suggestion is to put
total = price * quantity; after stringstream(mystr) >> quantity;
auto total = [&]() { return price * quantity; };
and then use total()
http://coliru.stacked-crooked.com/a/27ba0fa6978ec9e1