Summary prototype and if structures - c++

So I need to create a function that will turn the COUT part ONLY of each "if" statement:
// Respond to the user's menu selection
if (choice == ADULT_CHOICE)
{
charges = months * ADULT;
cout << over3 << "The total charges are $" << charges << endl;
}
else if (choice == CHILD_CHOICE)
{
charges = months * CHILD;
cout << over3 << "The total charges are $" << charges << endl;
}
else if (choice == SENIOR_CHOICE)
{
charges = months * SENIOR;
cout << over3 << "The total charges are $" << charges << endl;
}
Into a summary function that reads like THIS.
So far I have made a total mess of the code and I really need some help... here is what I have so far but most of it is probably not salvageable:
function prototype:
int summary(string, int, int, double);
Main:
//variables
int choice; // menu choice
int months; //number of months
double charges; //monthly charges
string type1 = "Adult", type2 = "Child", type3 = "Senior";
if (choice == ADULT_CHOICE)
{
charges = months * ADULT;
cout << summary(type1, months, 40, charges);
}
else if (choice == CHILD_CHOICE)
{
charges = months * CHILD;
cout << summary(type2, months, 20, charges);
}
else if (choice == SENIOR_CHOICE)
{
charges = months * SENIOR;
cout << summary(type3, months, 30, charges);
}
function definition:
int summary(string type, int months, int price , double charges)
{
system("CLS");
cout << down7;
cout << over3 << " Summary of Charges \n"
<< over3 << "----------------------------\n"
<< over3 << "Membership Type: " << type << endl;
cout << over3 << "Number of Months: " << months << endl;
cout << over3 << "Membership Prices: " << price << endl;
cout << over3 << "Total of Charges: " << charges << endl;
}
I know there is a lot wrong here and I just needed some help going in the right direction. I have no idea how to solve the string variable stuff, should I keep going that route? or go an other way entirely?
Thanks for any help!

There are several designs and implementations for your requirements.
switch statement
Instead of all these if-else-if in a ladder, use a switch statement. I believe a switch statement would be more readable:
double rate = 0.0;
std::string type_name;
double price = 0.0;
switch (choice)
{
case ADULT_CHOICE:
rate = adult_rate;
type_name = "Adult";
price = 40;
break;
case CHILD_CHOICE:
rate = child_rate;
type_name = "Child";
price = 20;
break;
case SENIOR_CHOICE:
rate = senior_rate;
type_name = "Senior";
price = 30;
break;
default:
cerr << "Invalid ticket type\r\n";
exit(1);
}
charges = months * rate;
summary(type_name, months, price, charges);
Look up table
A more maintainable design and implementation is to use a look up table. Create a table of entries that contain information about a ticket. (This will lead up to the last design consideration).
struct Ticket
{
unsigned int choice;
char const * type_name;
double price;
double rate;
};
const Ticket ticket_info[] =
{
{ADULT_CHOICE, "Adult", 40, ADULT_RATE},
{CHILD_CHOICE, "Child", 10, CHILD_RATE},
{SENIOR_CHOICE, "Senior", 30, SENIOR_RATE},
};
const unsigned int maximum_ticket_types =
sizeof(ticket_info) / sizeof(ticket_info[0]);
for (unsigned int i = 0; i < maximum_ticket_types; ++i)
{
if (choice == ticket_info[i].choice)
{
summary(ticket_info[i].type_name,
months,
ticket_info[i].price,
ticket_info[i].rate * months);
break;
}
}
This has the advantage that you can test it with only 1 entry and then add additional entries without adding additional code.
Object Oriented
In the Object Oriented approach, you would have either a ticket object (like the structure above) or have Parent Ticket and child ticket objects. The objects would contain methods for printing a summary.
Here is a sample:
class Ticket_Base
{
public:
friend std::ostream& operator>>(std::ostream& output, const Ticket_Base& ticket);
double rate;
double price;
std::string type_name;
};
class Adult_Ticket : public Ticket_Base
{
public:
Adult_Ticket()
: rate(ADULT_RATE), price(40), type_name("Adult");
};
The senior and child ticket classes would look the same as the adult ticket.
You could use the Factory Pattern to create tickets and a generic function to print the ticket summary.

Related

Doing while loop properly until "0" input to stop the loop?

I need help. I'm currently learning C++ programming and I'm still at the beginner level. I'm still figuring out how to make the while loop working. My idea is when inserting the correct code input, the switch statement choose the right case statement and loop back to insert another input until 0 inserted to stop the loop and calculate for the final output in main() constructor.
I know I have few kinks to fix soon but I'm still struggling to figure out this particular part.
#include <stdio.h>
#include <iostream>
#include <iomanip>
using namespace std;
double sst = 0.06, total = 0, grandTotal, price, discount, newPrice, totalSST;
int quantity, count, code;
string name, ech;
void item001(){
name = "Rice (5kg)";
price = 11.5;
discount = 0;
}
void item002(){
name = "Rice (10kg)";
price = 25.9;
discount = 0;
}
void item003(){
name = "Sugar (1kg)";
price = 2.95;
discount = 0;
}
void item_cal(){
cout << "Please enter the quantity of the item: ";
cin >> quantity;
newPrice = (price + (discount * price)) * quantity;
cout << "\nItem: " << name << " || Quantity: " << quantity << " || Price: RM" << newPrice << endl;
}
void input(){
cout << "Welcome SA Mart\n" << "Please insert the code. Press 0 to stop: ";
while (code != 0){
cin >> code;
switch (code){
case 001:
item001();
item_cal();
break;
case 002:
item002();
item_cal();
break;
case 003:
item003();
item_cal();
break;
default:
cout << "\nWrong code" << endl;;
break;
total += newPrice;
}
}
}
int main(){
input();
totalSST = total * sst;
grandTotal = total + totalSST;
cout << fixed << setprecision(2);
cout << "Total: RM" << total << " ||SST: RM" << totalSST << " || Grand Total: RM" << grandTotal << endl;
return 0;
}
The only functional issue I see in your code is that there is a chance that the code variable will initialize to 0 (depends on the compiler/randomness). If that happens, your input method will return before it enters the loop. Other than that it looks like it will work. Of course, programming is not just the art of "making it work," style and readability are important too. In general, you want to confine variables to the smallest scope in which they are referenced. 'code' should not be a global variable, it should live in the input method. As for the loop, there are several ways it could be implemented: a "while(true)" loop could be used, in which case the variable may be defined inside the loop; on the other hand a "do while" would guarantee one loop runs (perhaps that would be a good fit here), but the variable must live outside of the loop, at least int the scope of conditional check. The way you choose is often a matter of style. Below, I use a "while(true)."
In programming, readability matters (a lot). I think this program would be easier to read if the data were broken up into a few structs, perhaps "Bill," and "Food." Another thing to consider is how to broaden the usage of your program, without introducing significant complexity. For example, it could work for any grocery store (any set of food items/prices). This is often a matter of determining an appropriate set of parameters to feed your program.
To do these things you might write something like this:
#pragma once
#include <string>
#include <map>
using namespace std;
namespace market {
const double& sst = 0.06;
struct Bill {
double total = 0;
double totalSST = 0;
double grandTotal = 0;
};
struct Food {
const char* name;
double price;
double discount;
Food(const char* name, double price, double discount = 0)
: name(name), price(price), discount(discount) {}
double result_price() const {
return price - price * discount;
}
};
struct GroceryStore {
const char* name;
std::map<int, Food> inventory;
GroceryStore(const char* name, std::map<int, Food> inventory)
: name(name), inventory(inventory) { }
};
void shop(const GroceryStore& store, Bill& bill, bool show_menu = false, int exit_code = 0) {
// check error conditions
if (store.inventory.find(exit_code) != store.inventory.end()) {
// that's the 'exit_code' code silly!
cout << "Bad store. Come back another time." << endl;
return;
}
cout << "Welcome to " << store.name << endl;
if (show_menu) {
cout << "The following items are available for purchase:" << endl;
for (auto p : store.inventory) {
cout << "\t" << p.first << ") " << p.second.name << "(" << p.second.result_price() << endl;
}
}
cout << "Enter the product code of the item you wish to purchase:";
int code;
cin >> code;
while (true) {
auto food_it = store.inventory.find(code);
if (food_it == store.inventory.end()) {
cout << "Thanks for stopping by." << endl;;
break;
}
cout << "Please enter the quantity of the item: ";
uint32_t quantity;
cin >> quantity;
auto& food = food_it->second;
auto disc_price = food.price - (food.discount * food.price);
bill.total += disc_price * quantity;
cout << "\nItem: " << food.name << " || Quantity: " << quantity << " || Price: RM" << disc_price << endl;
cout << "Would you like anything else? Enter the product code, or press " << exit_code << " to proceed to check-out." << endl;
cin >> code;
}
}
void ring_up(Bill& bill) {
bill.totalSST = bill.total * sst;
bill.grandTotal = bill.total + bill.totalSST;
}
void run() {
int code = 1;
GroceryStore store("SMart", {
{ code++, Food("Rice (5kg)", 11.5, 0) },
{ code++, Food("Rice (10kg)", 25.9) },
{ code, Food("Sugar (1kg)", 2.95, 0) }
});
Bill bill;
shop(store, bill, true);
ring_up(bill);
cout << "Total: RM" << bill.total << " ||SST: RM" << bill.totalSST << " || Grand Total: RM" << bill.grandTotal << endl;
}
}
Firstly there is a bug in input when u will input 0 then also it won't break while loop as code that is checked contains the previous value.
for example:
input is
3
0
but according to your code when the code will run the second time and while condition is checked code still contains 3 as value and code will run one more time
Try initialising code to some value, for example, -1. I'm not really sure but I think for global int variables, they initialise int variables to 0. So your first loop doesn't run. Or another way to do it is using do while loops instead of while loop.
do {
cin >> code;
switch (code){
case 001:
item001();
item_cal();
break;
case 002:
item002();
item_cal();
break;
case 003:
item003();
item_cal();
break;
default:
cout << "\nWrong code" << endl;;
break;
total += newPrice;
} while (code != 0);
}
This makes sure that the loop will run at least once, making code initialised.
Hope it helps you! Have fun programming!

Calculate the Discount Fitness Price (30%, 20% and 15% Off)

User - Defined Functions
The cost to become a member of a fitness center is as follows:
The senior citizens discount is 30%.
If the membership is bought and paid for 12 or more months, the discount is 15%
If more than five personal training sessions are bought and paid for, the discount on each session is 20%.
Write a menu-driven program that determines the cost of a new membership. Your program must contain a function that displays the general information about the fitness center and its charges, a function to get all of the necessary information to determine the membership cost, and a function to determine the membership cost. Use appropriate parameters to pass information in and out of a function. (Do not use any global variables.)
My codes:
#include <iostream>
#include <iomanip>
using namespace std;
// program constants
void setPrices(double&, double&);
void getInfo(bool&, bool&, bool&, int&, int&);
double membershipCost(double, int, double, int, bool, bool, bool);
void displayCenterInfo();
int main()
{
bool seniorCitizen;
bool boughtFiveOrMoreSessions;
bool paidTwelveOrMoreMonths;
int numberOfMembershipMonths;
int numberOfPersonalTrainingSessions;
double regularMembershipChargesPerMonth;
double costOfOnePersonalTrainingSession;
double memberCost;
cout << fixed << showpoint << setprecision(2);
displayCenterInfo();
cout << endl;
setPrices(regularMembershipChargesPerMonth, costOfOnePersonalTrainingSession);
getInfo(seniorCitizen, boughtFiveOrMoreSessions, paidTwelveOrMoreMonths, numberOfMembershipMonths, numberOfPersonalTrainingSessions);
// cal getInfo
memberCost = membershipCost(regularMembershipChargesPerMonth, numberOfMembershipMonths, costOfOnePersonalTrainingSession,
numberOfPersonalTrainingSessions, seniorCitizen, boughtFiveOrMoreSessions, paidTwelveOrMoreMonths);
cout << "$" << memberCost;
system("pause");
return 0;
}
void displayCenterInfo()
{
cout << "Welcome to Stay Healty and Fit center." << endl;
cout << "This program determines the cost of a new membership." << endl;
cout << "If you are a senior citizen, then the discount is 30% of "
<< "of the regular membership price." << endl;
cout << "If you buy membership for twelve months and pay today, the "
<< "discount is 15%." << endl;
cout << "If you buy and pay for 6 or more personal training session today, "
<< "the discount on each session is 20%." << endl;
}
void setPrices(double& regMemPrice, double& personalTrSesCost)
{
cout << "Please enter the cost of regular Membership per month: " << endl;
cin >> regMemPrice;
cout << "Please enter the cost of one personal traning session: " << endl;
cin >> personalTrSesCost;
}
void getInfo(bool& senCitizen, bool& bFiveOrMoreSess, bool& paidTwMnth,
int& nOfMonths, int& nOfPersonalTrSess)
{
//Senior Verification
char userInputSenior;
cout << "Are you Senior? Please enter 'Y' or 'N': ";
cin >> userInputSenior;
if (userInputSenior == 'y' && userInputSenior == 'Y')
{
senCitizen = true;
}
else
senCitizen = false;
cout << endl;
//Number of personal training session.
cout << "Enter the number of personal training sessions bought: ";
cin >> nOfPersonalTrSess;
if (nOfPersonalTrSess >= 5)
{
bFiveOrMoreSess = true;
}
else
bFiveOrMoreSess = false;
cout << endl;
//Number of months
cout << "Enter the number of months you are paying for: ";
cin >> nOfMonths;
if (nOfMonths >= 12)
{
paidTwMnth = true;
}
else
paidTwMnth = false;
}
double membershipCost(double regMemPricePerMth, int nOfMonths,
double personalTrSesCost, int nOfPersonalTrSess,
bool senCitizen, bool bFiveOrMoreSess, bool paidTwMnth)
{
double finalMembershipCost, finalSessionCost;
//Session Discount
if (bFiveOrMoreSess)
{
personalTrSesCost = personalTrSesCost * 0.8;
}
else
{
personalTrSesCost = personalTrSesCost;
}
//Month Discount
if (paidTwMnth)
{
regMemPricePerMth = regMemPricePerMth * 0.85;
}
else
{
regMemPricePerMth = regMemPricePerMth;
}
finalMembershipCost = regMemPricePerMth * nOfMonths;
finalSessionCost = personalTrSesCost * nOfPersonalTrSess;
// Check if Senior Citizen Discount Applies
if (senCitizen) {
return (finalMembershipCost * 0.7) + finalSessionCost ;
}
else {
return finalMembershipCost + finalSessionCost;
}
}
My Test Result
An error occurs on "Senior Citizen Discount".
Green color - My output.
Red color - Its output (Correct Answer).
I don't know how to get that answer ($2260.00) with my code. I have checked many times and I couldn't solve the problem. Please help me!
You should use an or-Statement for detecting if its a senior citizen:
if (userInputSenior == 'y' || userInputSenior == 'Y')
BTW: You have another small bug when calculating the discount for personal lessons, you only get a discount for more than 5 sessions, so the corresponding if-statement should be
(nOfPersonalTrSess > 5)
Thank you guys so much, I solved my problem!
Here is my complete program:
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
// program constants
void setPrices(double&, double&);
void getInfo(bool&, bool&, bool&, int&, int&);
double membershipCost(double, int, double, int, bool, bool, bool);
void displayCenterInfo();
int main()
{
bool seniorCitizen;
bool boughtSixOrMoreSessions;
bool paidTwelveOrMoreMonths;
int numberOfMembershipMonths;
int numberOfPersonalTrainingSessions;
double regularMembershipChargesPerMonth;
double costOfOnePersonalTrainingSession;
double memberCost;
cout << fixed << showpoint << setprecision(2);
displayCenterInfo();
cout << endl;
setPrices(regularMembershipChargesPerMonth, costOfOnePersonalTrainingSession);
getInfo(seniorCitizen, boughtSixOrMoreSessions, paidTwelveOrMoreMonths, numberOfMembershipMonths, numberOfPersonalTrainingSessions);
// cal getInfo
memberCost = membershipCost(regularMembershipChargesPerMonth, numberOfMembershipMonths, costOfOnePersonalTrainingSession,
numberOfPersonalTrainingSessions, seniorCitizen, boughtSixOrMoreSessions, paidTwelveOrMoreMonths);
cout << "$" << memberCost;
system("pause");
return 0;
}
void displayCenterInfo()
{
cout << "Welcome to Stay Healty and Fit center." << endl;
cout << "This program determines the cost of a new membership." << endl;
cout << "If you are a senior citizen, then the discount is 30% of "
<< "of the regular membership price." << endl;
cout << "If you buy membership for twelve months and pay today, the "
<< "discount is 15%." << endl;
cout << "If you buy and pay for 6 or more personal training session today, "
<< "the discount on each session is 20%." << endl;
}
void setPrices(double& regMemPrice, double& personalTrSesCost)
{
cout << "Please enter the cost of regular Membership per month: " << endl;
cin >> regMemPrice;
cout << "Please enter the cost of one personal traning session: " << endl;
cin >> personalTrSesCost;
}
void getInfo(bool& senCitizen, bool& bSixOrMoreSess, bool& paidTwMnth,
int& nOfMonths, int& nOfPersonalTrSess)
{
//Senior Verification
char userInputSenior;
cout << "Are you Senior? Please enter 'Y' or 'N': ";
cin >> userInputSenior;
if (userInputSenior == 'y' || userInputSenior == 'Y')
{
senCitizen = true;
}
else
senCitizen = false;
cout << endl;
//Number of personal training session.
cout << "Enter the number of personal training sessions bought: ";
cin >> nOfPersonalTrSess;
if (nOfPersonalTrSess > 5)
{
bSixOrMoreSess = true;
}
else
bSixOrMoreSess = false;
cout << endl;
//Number of months
cout << "Enter the number of months you are paying for: ";
cin >> nOfMonths;
if (nOfMonths >= 12)
{
paidTwMnth = true;
}
else
paidTwMnth = false;
}
double membershipCost(double regMemPricePerMth, int nOfMonths,
double personalTrSesCost, int nOfPersonalTrSess,
bool senCitizen, bool bSixOrMoreSess, bool paidTwMnth)
{
double finalMembershipCost, finalSessionCost;
//Session Discount
if (bSixOrMoreSess)
{
personalTrSesCost = (personalTrSesCost * 0.8);
}
else
{
personalTrSesCost = personalTrSesCost;
}
//Month Discount
if (paidTwMnth)
{
regMemPricePerMth = regMemPricePerMth * 0.85;
}
else
{
regMemPricePerMth = regMemPricePerMth;
}
finalMembershipCost = regMemPricePerMth * nOfMonths;
finalSessionCost = personalTrSesCost * nOfPersonalTrSess;
// Check if Senior Citizen Discount Applies
if (senCitizen) {
return (finalMembershipCost * 0.7) + finalSessionCost;
}
else {
return finalMembershipCost + finalSessionCost;
}
}

Possible to loop through an array structure in C++

Apologize ahead of time if this may have been answered previously. Didn't find anything (or wasn't using the correct search terms). Regardless, There is a specific part of my code I wanted to know if I could step through with a loop. I went ahead and added the code below. Two sections that I feel could probably be cleaned up is the request for user input for how much was spent on various budget categories. I had plan to use a for loop, but couldn't figure how to assign values to various elements of the MonthlyBudget structure "currentMonthlyBudget" (i.e. currentMonthlyBudget.housing, currentMonthlyBudget.utilities, etc). It would have worked for the expenseCategories[], but I could find how (or if it is possible) to do it for the structure. Any assistance would be appreciated. Thanks in advance.
/* Exercise_10.cpp Monthly Budget Calculation*/
#include <iostream>
#include <iomanip>
#include <string>
#include <cmath>
using namespace std;
struct MonthlyBudget
{
double housing; //Housing
double utilities; //Utilities
double householdExpense; //Household Expense
double transportation; //Transportation
double food; //Food
double medical; //Medical
double insurance; //Insurance
double entertainment; //Entertainment
double clothing; //Clothing
double misc; //Miscellaneous
};
int main()
{
//Array of Monthly Budget Values
double defaultMonthlyBudget[10] = { 500.00, 150.00, 65.00,
50.00, 250.00, 30.00,
100.00, 150.00, 75.00,
50.00 };
//Array of Expense Categories
string expenseCategories[10] = { "Housing Accomodations", "Utilities", "Household Expenses",
"Transporation", "Food", "Medical Expenses", "Insurance",
"Entertainment", "Clothing", "Miscellaneous Expenses" };
//Array to hold the over budget and under budget values
double actualBudget[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
//Accumulator for actual budget
double sum = 0.00;
//Loop counter
int index;
//Final Total Budget
double calculatedTotalBudget = 0.00;
//Structure
MonthlyBudget currentMonthlyBudget;
cout << "Greetings. This program will determine if you are meeting your agreed upon budget." << endl;
cout << "I will ask you questions about your spending habits, and return a report to see how\n";
cout << "you did this month. Lets get started!\n\n\n";
cout << "\nPlease type in how much was spent this month for " << expenseCategories[0] << ": ";
cin >> currentMonthlyBudget.housing;
cout << "\nPlease type in how much was spent this month for " << expenseCategories[1] << ": ";
cin >> currentMonthlyBudget.utilities;
cout << "\nPlease type in how much was spent this month for " << expenseCategories[2] << ": ";
cin >> currentMonthlyBudget.householdExpense;
cout << "\nPlease type in how much was spent this month for " << expenseCategories[3] << ": ";
cin >> currentMonthlyBudget.transportation;
cout << "\nPlease type in how much was spent this month for " << expenseCategories[4] << ": ";
cin >> currentMonthlyBudget.food;
cout << "\nPlease type in how much was spent this month for " << expenseCategories[5] << ": ";
cin >> currentMonthlyBudget.medical;
cout << "\nPlease type in how much was spent this month for " << expenseCategories[6] << ": ";
cin >> currentMonthlyBudget.insurance;
cout << "\nPlease type in how much was spent this month for " << expenseCategories[7] << ": ";
cin >> currentMonthlyBudget.entertainment;
cout << "\nPlease type in how much was spent this month for " << expenseCategories[8] << ": ";
cin >> currentMonthlyBudget.clothing;
cout << "\nPlease type in how much was spent this month for " << expenseCategories[9] << ": ";
cin >> currentMonthlyBudget.misc;
cout << "\n\n\n";
//Compare inputted values to those of the predetermine budget
actualBudget[0] = (defaultMonthlyBudget[0] - currentMonthlyBudget.housing);
actualBudget[1] = (defaultMonthlyBudget[1] - currentMonthlyBudget.utilities);
actualBudget[2] = (defaultMonthlyBudget[2] - currentMonthlyBudget.householdExpense);
actualBudget[3] = (defaultMonthlyBudget[3] - currentMonthlyBudget.transportation);
actualBudget[4] = (defaultMonthlyBudget[4] - currentMonthlyBudget.food);
actualBudget[5] = (defaultMonthlyBudget[5] - currentMonthlyBudget.medical);
actualBudget[6] = (defaultMonthlyBudget[6] - currentMonthlyBudget.insurance);
actualBudget[7] = (defaultMonthlyBudget[7] - currentMonthlyBudget.entertainment);
actualBudget[8] = (defaultMonthlyBudget[8] - currentMonthlyBudget.clothing);
actualBudget[9] = (defaultMonthlyBudget[9] - currentMonthlyBudget.misc);
//TEST
/*for (index = 0; index < 10; index++)
{
cout << actualBudget[index] << "\n";
}*/
//Add up actualBudget
for (index = 0; index < 10; index++)
{
sum += actualBudget[index];
}
//Assign value to Calculated Total Budget
calculatedTotalBudget = (1420.00 - sum);
//Loop to display what categories we went over, under, & met our budget
for (index = 0; index < 10; index++)
{
if (actualBudget[index] < 0.00)
{
cout << "For the category of " << expenseCategories[index] << ", you went over your budget by $" << abs(actualBudget[index]) << ".\n";
}
else if (actualBudget[index] > 0.00)
{
cout << "For the category of " << expenseCategories[index] << ", you came in under your budget by $" << abs(actualBudget[index]) << ".\n";
}
else
{
cout << "For the category of " << expenseCategories[index] << ", you met your budget exactly.\n";
}
}
//Provide information to the user if the grand total went over, under, or met our total budget
if (calculatedTotalBudget > 1420.00)
{
cout << "This month's total expenditure was $" << calculatedTotalBudget << ". You were over budget by $" << (calculatedTotalBudget - 1420.00) << ".\n";
}
else if (calculatedTotalBudget < 1420.00)
{
cout << "This month's total expenditure was $" << calculatedTotalBudget << ". You were under budget by $" << abs(1420.00 - calculatedTotalBudget) << ".\n";
}
else
{
cout << "This month's total expenditure was $" << calculatedTotalBudget << ". You met your budget exactly.\n";
}
}
A clean solution could be to just hold a vector of categories and references to the values they map to
//Array of Expense Categories
std::vector<std::pair<string, double&>> expenseCategories = {
{ "Housing Accomodations", currentMonthlyBudget.housing },
{ "Utilities", currentMonthlyBudget.utilities },
{ "Household Expenses", currentMonthlyBudget.householdExpense },
{ "Transporation", currentMonthlyBudget.transportation },
{ "Food", currentMonthlyBudget.food },
{ "Medical Expenses", currentMonthlyBudget.medical },
{ "Insurance", currentMonthlyBudget.insurance },
{ "Entertainment", currentMonthlyBudget.entertainment },
{ "Clothing", currentMonthlyBudget.clothing },
{ "Miscellaneous Expenses", currentMonthlyBudget.misc }
};
Any loop will then just use either the category description or the value it maps to
for (auto& category : expenseCategories) {
cout << "\nPlease type in how much was spent this month for " << category.first << ": ";
cin >> category.second;
}
Live Example
The solution above has the advantage that you can reorganize your fields as you wish and just update the references involved.
For a simple data structure like the one you have you might as well have referred to its fields as in a simple array (i.e. by getting the pointer to the first element and then iterating over those).
If you really want to make a for loop from the MonthlyBudget input, you can do it by creating an array of a simple struct:
struct BudgetInputInfo {
std::string message;
double& targetValue;
}
Just create a static array of this, and you can write your for loop based on that array.
You can even add a method to this struct which displays the message, and sets targetValue.
Later, when you have other members than doubles, you can change this into a template.
But I think this won't result in the most readable code, you won't get a real benefit from the for loop, unless you want to be able to change the list it's based on runtime.
If your list is fixed like in the example, creating a function which prints out the message and reads the input would be more readable:
void readInput(std::string targetName, double& target) {
cout << "Please type in how much was spent this month for " << targetName << ": ";
cin >> target;
cout << endl;
}
With this, you would only have a few relatively short readInput calls.
You can even make a function which reads every member of a MonhtlyBudget:
void readMonhtlyBudget(MonthlyBudget& m) {
readInput("Housing Accomodations", m.housing);
// ...
}
Also, I would change your 10 element arrays to be instances of MonthlyBudgets. It's more clear, and you can even keep your current initializer syntax if you are using C++11:
MonthlyBudget defaultBudget = { 500.00, 150.00, 65.00,
50.00, 250.00, 30.00,
100.00, 150.00, 75.00,
50.00 };
And move the difference calculation code into a separate method, preferrable operator-:
MonthlyBudget operator-(MonthlyBudget const& a, MonthlyBudget const& b) {
MonthlyBudget result;
result.housing = a.housing - b.housing;
// ...
return result;
}
With these changes, you can just write:
actualBudget = defaultBudget - currentMonthlyBudget;

C++ Calculation Problem, Always returns $0

I have to display and loop a menu, allowing the customer to make multiple orders for peanuts, movies, or books. The menu displays fine, but the quantity doesn't go down to the calculations part of my code. Everytime I enter a quantity for anything and checkout it returns $0. I have no idea why this is happening I don't see anything wrong with my code, but obviously there is. Do you guys have any suggestions on what to do based on looking at what I have?
#include <iostream>
#include <cstdlib>
using namespace std;
//function declarations
void displayMenu();
//constant statements
const double BOOK_PRICE = 9.00; //price per book
const double BOOK_SHIPPING = 1.06; //shipping per book
const double MOVIE_PRICE = 13.99; //price per movie
const double MOVIE_SHIPPING = .05; //shipping per movie subtotal
const double PEANUT_PRICE = 1.80; //price of peanuts per pound
const double SHIPPING_PRICE = .50; //shipping of peanuts per lb
int main()
{
//declaration statements
int numBooks = 0; //# of books purchased
int numMovies = 0; //# of movies purchased
double numPeanuts = 0.0; //# of peanuts per pound
double bookSubtotal = 0.0; //subtotal of books
double movieSubtotal = 0.0; //subtotal of movies
double peanutSubtotal = 0.0; //subtotal of peanuts
int totalBooks = 0; //running total of books
int totalMovies = 0; //running total of movies
double totalPeanuts = 0.0; //running total of peanuts
int userChoice = 0; //user input
double totalPrice = 0.0; //final price
while (userChoice != 4)
{
displayMenu();
cout << "Enter a menu choice: ";
cin >> userChoice;
if (userChoice == 1)
{
cout << "Please enter the number of books: ";
cin >> numBooks;
totalBooks = totalBooks + numBooks;
}
else if (userChoice == 2)
{
cout << "Please enter the number of movies: ";
cin >> numMovies;
totalMovies = totalMovies + numMovies;
}
else if (userChoice == 3)
{
cout << "Please enter the pounds of peanuts as a decimal: ";
cin >> numPeanuts;
totalPeanuts = totalPeanuts + numPeanuts;
}
else if (userChoice == 4)
{
break;
}
else
{
cout << "Invalid Input" << endl;
}
}
//computations
bookSubtotal = (totalBooks * BOOK_PRICE) + (totalBooks * BOOK_SHIPPING);
movieSubtotal = (totalMovies * MOVIE_PRICE * .05) + (totalMovies * MOVIE_PRICE);
peanutSubtotal = (PEANUT_PRICE * totalPeanuts) + (totalPeanuts * .5);
totalPrice = bookSubtotal + movieSubtotal + peanutSubtotal;
cout << "The total price is $" << totalPrice << endl;
system("PAUSE");
return 0;
}//end of main
void displayMenu()
{
cout << "1 Books" << endl;
cout << "2 Movies" << endl;
cout << "3 Peanuts" << endl;
cout << "4 Checkout" << endl;
}//end of displayMenu
The problem is in the cin >> - you found the answer yourself when you say that the book count is zero. I suggest you try to put << endl after each cout << .... Other solution is to use _flushall(); after each cout.

Functions and structures in C++

/*I got stumped within my code. I think classes will be simpler than structures, but the chapter within my book makes me do structures. : / I am currently getting an error message that my function was not matched up for an overloaded function. The book does talk about them, but the examples of overloading functions in the book aren't helping me out. Also the book wants me to enter account numbers and fill in the objects and when they are asked for an account number they should have the opportunity to "QUIT" entering numbers and proceed onto the next part of the program; that whole way of thinking has my brain a bit fried and I was hoping I could get some help. I apologize if the formatting of my code is messy, I tried to reformat it within here so it would all go into the code brackets.
The Error happens at line... 161 at the displayAccounts function. Parameters were different within the top and bottom of the two functions I changed it and it works. I am going to go over different parts and if its correct post the correct code.*/
I figured out exactly the question that I need. I need the "QUIT" loop to be allowed to be followed up within the account numbers. This would allow the user to enter in a 0 at any time when asked to enter an account number and this was what was confusing me the most.
#include <iostream>
#include <iomanip>
using namespace std;
struct BankAccount
{
void enterAccountsData(BankAccount *accounts);
void computeInterest(BankAccount *accounts);
void displayAccounts(BankAccount *accounts, const int QUIT);
int accountNum; // holds the account number.
double accountBal; // holds the account balance.
double annualInterest; // holds the interest rate.
int term; // holds the term for the accounts.
};
int main()
{
const int MAX_ACCOUNTS = 100; // The maximum number of bank accounts.
const int QUIT = 0; // sentinal value.
int input;
int num = 0;
BankAccount data[MAX_ACCOUNTS];
BankAccount display;
cout << "Enter " << QUIT << " to stop, otherwise enter 1 and procreed.";
cin >> input;
while(true)
{
if(input != QUIT)
{
data[MAX_ACCOUNTS].enterAccountsData(data);
data[MAX_ACCOUNTS].computeInterest(data);
}
else
{
break;
}
}
display.displayAccounts(data, QUIT);
//system("pause");
return 0;
}
void BankAccount::enterAccountsData(BankAccount *accounts)
{
cout << setprecision(2) << fixed;
const int NUM_OF_ACCOUNTS = 100; // the number of bank accounts. (change the number for more bank accounts)
int found;
int quit = 0;
/* First for loop which asks and holds the account information
entered in by the user. */
for(int num = 0; num < NUM_OF_ACCOUNTS; num++)
{
do
{
found = 0;
cout << "Enter in account # " << (num + 1) << endl;
cin >> accounts[num].accountNum; // holds the value of the account number
// Checks if the account number is valid.
while(accounts[num].accountNum < 999 || accounts[num].accountNum > 10000)
{
cout << "Account number must be four didgets:" << endl;
cin >> accounts[num].accountNum;
}
// Checks if the account numbers are the same.
for(int check = 0; check < num; check++)
{
while(accounts[num].accountNum == accounts[check].accountNum)
{
cout << endl << "Account Numbers cannot be the same, enter in a new account number." << endl;
found = 1;
break;
}
}
} while(found); // end of do while.
// Holds the values for the account balances.
cout << "Enter the accounts balance." << endl;
cin >> accounts[num].accountBal;
// Makes sure that the account balance is not negative.
while(accounts[num].accountBal < 0)
{
cout << "Account cannot have a negitive balance." << endl;
cin >> accounts[num].accountBal;
}
// Holds the interest rate.
cout << endl << "Enter the interest rate for account # " << (num + 1) << endl;
cin >> accounts[num].annualInterest;
// Makes sure the interest rate is valid
while(accounts[num].annualInterest > 0 && accounts[num].annualInterest > 0.15)
{
cout << endl << "Annual interest must be from 0 to 0.15." << endl;
cin >> accounts[num].annualInterest;
}
// Makes sure the interest rate is not negetive
while(accounts[num].annualInterest < 0)
{
cout << endl << "Interest rate cannot be negetive" << endl;
cin >> accounts[num].annualInterest;
}
// Holds the value for the length of the interest.
cout << endl << "How many years will this interest rate be held for? " << endl;
cin >> accounts[num].term;
//Checks for valid length of time for the term held
while(accounts[num].term < 0 || accounts[num].term > 11)
{
cout << "The Term must be greater than 1 and should not exceed 10" << endl;
cin >> accounts[num].term;
}
}
cout << "If you wish to stop enter 0 otherwise type 1 to proceed" << endl;
cin >> quit;
if(quit = 0)
{
return;
}
}
void BankAccount :: computeInterest(BankAccount *accounts)
{
const int NUM_OF_ACCOUNTS = 100; // the number of bank accounts.
const int MONTHS_IN_YEAR = 12;
double total = 0;
double average = 0;
for(int num = 0; num < NUM_OF_ACCOUNTS; num++)
{
/*Goes through the term year and calculates the total
of each account balance. Then calculates the average. */
for(int year = 0; year < accounts[num].term; year++)
{
for(int month = 0; month < MONTHS_IN_YEAR; month++)
{
accounts[num].accountBal = (accounts[num].accountBal * accounts[num].annualInterest) + accounts[num].accountBal;
}
int month = 1;
cout << endl << "Total amount for account # " << (num + 1) << " is: " << accounts[num].accountBal << endl ;
total += accounts[num].accountBal;
cout << endl << "The total amount of all accounts is: " << total << endl;
}
}
average = total / NUM_OF_ACCOUNTS;
cout << "Average of all the bank accounts is: " << average << endl;
}
void BankAccount :: displayAccounts(BankAccount *accounts)
{
int input = 0;
int found;
const int MAX_ACCOUNTS = 100;
int quit = 0;
cout << endl << "Which account do you want to access?" << endl <<
"To stop or look at none of the account numbers type: " << quit << endl;
cin >> input;
for(int num = 0; num < MAX_ACCOUNTS; num++)
{
while(num < MAX_ACCOUNTS && input != accounts[num].accountNum)
{
num++;
}
if(input == accounts[num].accountNum) // This if sees if an account matches what the user entered.
{
cout << "Account: " << accounts[num].accountNum << endl << "Balance is: " <<
accounts[num].accountBal << endl << "Interest rate is: " << accounts[num].annualInterest;
cout << endl << "Enter another account number or type 0 to quit." << endl;
found = 1;
cout << endl;
cin >> input;
}
if(found == 0)
{
cout << "Sorry that account doesn't exist. Enter another account number." << endl;
cin >> input;
}
}
}
In C++, classes and structs are exactly the same constructs. They are, in fact, one thing — a User-Defined Type.
There is a different that is invoked depending on whether you used the keyword struct or class to define your UDT, and that is that class-key defaults to private member access and private inheritance, whereas struct-key defaults to both being public.
Other than this syntax difference, you can use either without worrying about one being "simpler" than the other.
Anyway, your compiler error (please provide it next time) is probably due to a declaration/definition mismatch.
Your declaration:
void displayAccounts(BankAccount *accounts, const int QUIT);
Start of your definition:
void BankAccount :: displayAccounts(BankAccount *accounts) {
The start of the definition should be
void BankAccount::displayAccounts(BankAccount* accounts, const int QUIT) {
to match. I've also fixed your spacing to be nicer. :)
void displayAccounts(BankAccount *accounts, const int QUIT);
... looks different between declaration and definition. Second parameter is missing in the definition.
Not sure what your question is, but classes and structs in C++ are equivalent except that fields are public by default in structs, but private by default in classes.
In the struct’s displayAccounts() member declaration you have:
void displayAccounts(BankAccount *accounts, const int QUIT);
and when defining the method later:
void BankAccount :: displayAccounts(BankAccount *accounts)
You have just missed
const int QUIT
parameter for the member function definition.