Function and selection issue in C++ - c++

I revised this post. I am new to programming and do not know if the functions are set up correctly or even how to allow the selection of packages. Below is my objective.
I have a class assignment to write a C++ program that will calculate a customers monthly internet bill. It would input a customer name, which package the customer purchased, and how many hours were used.
The Requirements are:
Input validation: to be sure the user only selects package A B or C. Display and error message if the wrong package is entered.
Calculation:
PackA for 9.95 a month with 10 hours of acess. 2 bucks per additional hour.
PackB for 14.95 a month with 20 hours of acess. 1 bucks per additional hour.
PackC for 19.95 a month with unlimited acess.
I then have to create the output as a bill.
The code I wrote so far is:
/*
James Hayek
CIS 165
Passaic County Community College
Program 04
*/
#include <iostream>
#include <iomanip>
using namespace std;
double calcBill(double packageChoosen, double hours, double basePack, char name); // This is the function prototype for calcBill
void dispBill(char packageChoosen, double hours, double basePack, char name, char bill); // This is the function prototype for dispBill
int main()
{
char packageChoosen;
double bill;
char name;
double hours;
double basePack;
cout << "Welcome To Your Personal Bill Caclculator!\n\n";
cout << "Please enter your name: \n";
cin >> name;
cout << "Please choose your package by entering A, B, or C: \n";
cin >> packageChoosen;
bill = calcBill(name, packageChoosen, hours, basePack); // call function calcBill
dispBill(name, packageChoosen, hours, basePack, bill); // call function dispBill
return 0;
} // end main
double calcBill(char packageChoosen, double hours, double basePack, char name) //This is the function for calcBill
{
if (packageChoosen == 'A' || packageChoosen == 'a' && hours <= 10)
{
bill = 9.95;
}
else if (packageChoosen == 'A' || packageChoosen == 'a' && hours > 10)
{
bill = 9.95 + (2 * hours);
}
else
{
cout << "Please choose an apropriate package";
}
return bill;
} // end main
void dispBill(double packA, double packB, double packC, char name, char bill) //This is the function for dispBill
{
cout << bill;
return;
} // end dispBill
I am not really sure where to begin, any advice would be greatly appreciated.

The && operator binds more tightly than the || operator in C++. Rather than
packageChoosen == 'A' || packageChoosen == 'a' && hours > 10
as a boolean expression, you most likely want
(packageChoosen == 'A' || packageChoosen == 'a') && hours > 10
The top expression looks either for a "package A" or a "package a with hours > 10". The bottom expression looks for a "package A or package a" and "hours > 10".
As Platinum Azure mentions in his answer, it is also possible to convert whatever character you have to lowercase, then do a single comparison against a lowercase letter.
#include <cctype>
// ...
std::tolower(packageChoosen) == 'a' && hours > 10
This makes your code a little more readable, and you don't have to worry about operator precedence.

Zeke's answer is solid; however, you could #include <cctype> and use std::tolower(packageChoosen == 'a' as part of your condition.

You need to think more in terms of OO. You're stuck in C world. I would suggest that Package would be a great candidate for an object.
As to the errors, you haven't said what they are so I can't really help you there. I'm too lazy to run a compile myself just to get what you should have already posted.

create an abstract class PackageAbstract
create a class called user
create a class called bill
create concretes class PackageA, packageB, packageC
in the user class add method :
addPackage(packageAbstract* packageAbs){}
add the member m_vector package choosen
for billing create a bill with user fedded with package...
each month you loop through users to create bills
for a real app you'll need a class custormers wich is feeded by users
...

Nice solution:
Create an abstract class Package, like so:
class Package{
public:
virtual double calculate(double hours) = 0;
}
Then subclass concrete package types from it, like so:
class PackageA : public Package{
public:
virtual double calculate(double hours){
return hours < 10 ? 9.92 : 9.95 + hours*2;
}
}
Then, you can use something like this code to calculate the bill:
Package* bill_calculators[3];
bill_calculators[0] = new PackageA();
bill_calculators[1] = new PackageB();
bill_calculators[2] = new PackageC();
char packageChosen;
cin >> packageChosen;
packageChosen = toupper(packageChosen) - 'A';
if(packageChosen >= 0 && packageChosen < 3) cout << bill_calculators[packageChosen]->calculate(hours);
else cout << "Invalid package\n";
I haven't actually compiled or tested the code, but you get the idea: create an abstract interface, implement algorithms for particular packages in subclasses, then create instances and decide which instance to use for calculation based on user input.
Btw, you'll have to #include to use the toupper() function
Cheers.

Related

Intro to classes (c++) project wants us to create two constructors, but neither of them need any parameters - what should i do here?

I think I'm just confused on the wording to this project, but I'm posting here to make sure I have the basics on classes correct (like I said, we just started learning them).
The beginning of the project prompt is as follows:
Declare and define a class called Odometer. This class will have two private variables, one for the miles driven and the other for the gallons of gas pumped into the car.
The member functions should include:
A constructor that takes initial values for both of the private variables.
A default constructor that sets both values to zero.
Along with more member functions that aren't important for my problem. I understand the default constructor fully, but the other is the one I'm having troubles with. If he (my professor) wants us to gather initial variables, then why would it need any parameters at all? I guess I could pass an empty string into it as a parameter, but I feel like there's something I'm missing here...
To expand on the point of this project, in case it's needed, we are creating a program that allows the user to continually enter (on a menu screen) either miles driven or gallons put into their tank. The program will then find the mpg, when the user requests it. Very simple.
Here's part of the program, which should be enough for someone to help me with this. The second/non-default constructor seems like it would work, except obviously I need some type of parameter. Any suggestions or help is greatly appreciated.
#include <iostream>
using namespace std;
class Odometer{
public:
Odometer(); // sets values to 0
Odometer(WHAT GOES HERE); // gathers initial values
void get_miles();
void get_gallons();
void add_in_trip_miles();
void add_gas();
private:
double milesDriven; // represents the miles the car has driven
double gallonsGas; // represents the number of gallons pumped into car
};
int main() {
Odometer userInfo; // creates object for the user-inputted values
bool quit = false; // true when user wants to quit
int userChoice; // for navigating the menu screen
while(!quit){
cout << "To view total miles, enter 1. To view total gallons, enter 2.\nTo record more miles driven, enter 3. To record gallons pumped into the tank, enter 4.\n To view the average MPG, enter 5. To reset the odometer, enter 6.\n To quit the program, enter 7." << endl;
cin >> userChoice;
if(userChoice == 1) userInfo.get_miles(); // TODO: switch/case statement instead?
if(userChoice == 2) userInfo.get_gallons();
if(userChoice == 3) userInfo.add_in_trip_miles(); // TODO: "function which increases the miles by the amount sent in its parameter
}
cout << "Have a nice day!" <<endl;
return 0;
}
Odometer::Odometer(){ // sets values to 0 (default)
milesDriven = 0;
gallonsGas = 0;
}
Odometer::Odometer(WHAT GOES HERE?){ // gathers initial values
cout << "Please enter an initial value for miles driven." << endl;
cin >> milesDriven;
cout << "Please enter an initial value for how many gallons were put into the car." << endl;
cin >> gallonsGas;
}
Your teacher is asking you to implement the second constructor with parameters so user will be able to initialize the object with the state he wants. I would implement it like this:
Odometer(double milesDriven_, double gallonsGas_) :
milesDriven(milesDriven_),
gallonsGas(gallonsGas_)
{}

C++ error: Out of range: basic_string

I just started learning programming a few months ago and so far I haven't encountered any error that google search can't solve until this one.
This simple program asks the user for 3 inputs, movie name, sales of adult and child tickets. Then, displays the profit.
Every time I enter a number for the second and third inputs, I get the error:
libc++abi.dylib: terminating with uncaught exception of type >std::out_of_range: basic_string
I am sorry if this question had been asked hundreds of time, but I can't seem to fix the problem myself.
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
int adultPrice= 12, childPrice= 6,
adultSold, childSold,
totalLength, theatreLength, disLength,
totalLength2, theatreLength2, disLength2,
totalProfit, theatreProfit, disProfit;
const double theatre = 0.2;
string movie,
totalString, theatreString, disString;
cout<<"This program calculates a theater's gross and net box office profit for a night."<< endl;
cout<<"Which movie are you calculating? ";
getline(cin,movie);
cout<<"How many adult and children tickets were sold?(Please enter adult tickets first and separate by a space) ";
cin>>adultSold>>childSold; \\ The number of tickets sold.
totalProfit = adultSold * adultPrice + childSold * childPrice;
theatreProfit = totalProfit * theatre;
disProfit = totalProfit - theatreProfit;
totalString = to_string(totalProfit);
theatreString = to_string(theatreProfit);
disString = to_string(disProfit);
totalLength2 = totalLength = totalString.length();
theatreLength2 = theatreLength = theatreString.length();
disLength2 = disLength = disString.length();
while(totalLength > 3)
{
totalLength -= 3;
totalString.insert(totalLength, ",");
}
while(theatreLength > 3)
{
theatreLength -= 3;
theatreString.insert(theatreLength, ",");
}
while(disLength > 3)
{
disLength -= 3;
disString.insert(disLength, ",");
}
totalString.insert(totalLength2+1,".00");
theatreString.insert(theatreLength2+1,".00");
disString.insert(disLength2+1,".00");
cout<<setw(30)<<"Movie Name: "<<setw(20)<<left<< movie <<endl;
cout<<setw(30)<<"Adults tickets sold: "<<setw(20)<<left<< adultSold <<endl;
cout<<setw(30)<<"Children tickets sold: "<<setw(20)<<left<< childSold <<endl;
cout<<setw(30)<<"Gross Box Office Profit: "<<"$"<<setw(20)<<left<< totalString <<endl;
cout<<setw(30)<<"Net Box Office Profit: "<<"$"<<setw(20)<<left<< theatreString <<endl;
cout<<setw(30)<<"Amount Paid to Distributor: "<<"$"<<setw(20)<<left<< disString <<endl;
}
Change these three lines to
totalString.insert(totalLength2,".00");
theatreString.insert(theatreLength2,".00");
disString.insert(disLength2,".00");
This corrects your problem because in c++ the memory locations used to contain the internal string data are stored in indexed buckets which are numbered from zero to length -1 with an additional null terminator at the end.
If you try to reference the position at length +1 you are referencing a location which is outside of the bounds of the internal string storage area.
For example, given a c++ string with a value 'mystring'.
string.c_str()[0] is equal to 'm'
string.c_str()[string.length()] is equal to '\0'
string.c_str()[string.length()+1] is undefined.

Getting "Statement missing ; in function main()" even though I have the semicolon already in C++

Here's the code assignment.
A bank charges $10 per month plus the following check fees for a commercial checking account:
$0.10 each for fewer than 20 checks
$0.08 each for 20-39 checks
$0.06 each for 40-59 checks
$0.04 each for 60 or more checks
The bank also charges an extra $15.00 if the balance of the account falls below $400 (before any check fees are applied). Write a program named lab2 that inputs for the beginning balance and the number of check written from the transaction file. Compute and display the bank's service fees for the month.
Input Validation: Do not accept a negative value for the number of checks written. If a negative value is given for the beginning balance, display an urgent message indicating the account is overdrawn.
The program should have a loop execution of six times for reading data from a file named transaction.txt.
Click the link transaction.txt download the file and store it in folder c:\cis180\lab2. The file transaction.txt contains the beginning balance and number of checks written for six transactions.
Here is the content of the file.
The text file
-100.00 -beginningbalance
30 - number of checks
400.00
-20
300.00
36
300.00
47
350.00
5
300.00
70
My code
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <sstream>
//include a library file to input data from file
using namespace std;
bool isNumeric(string pszInput);
int main()
{//start
// Constants
int numChecks; // Number of checks written for the month
double acctBalance; // Account balance before subtracting check fees
double checkFee; // Fee based on number of checks written
double totalFees; // Total monthly bank fees
ifstream inputFile;
//Open the file
inputFile.open("c:\\cis180\\transaction.txt");
//Initialize month counter
int transaction = 0; //first month
//Create a loop to execute 6 times. Each time the loop body reads the beginning balance and number of checks for six transaction, calculate the bank fees, display the beginning balance, number of checks, and the bank fees.
inputFile >> acctBalance;
// Display the beginning balance
if (acctBalance>0)
{
cout<<"Your beginning balance is: "acctBalance << endl;
}
else (acctBalance<0)
{
cout<<"Your account is overdrawn!" << endl;
}
// Display the number of checks that were written.
if (numChecks>0)
{
cout<<"The number of checks written were: "numChecks<<endl;
}
else (numChecks<0)
{
cout<<"Number of checks must be 0 or more."<<endl;
}
// Determine whether the account is overdrawn.
// Validate number of checks written.
// If the number of checks is less than 0
{ // numChecks is valid, so we can calulate the fees.
// Calculate checkFee - Use if/else if structure
const double MONTHLY_FEE= 10.00; // Base monthly fee
const double MIN_BAL= 400.00; // minimum balance
const double LOW_BAL_FEE= 15.00; // extra fee for low balance
for (int transaction = 0; transaction <=6; transaction++);
if (numChecks<20)
{
checkFee=(0.1*numChecks)+MONTHLY_FEE<<endl;
}
else if (numChecks<40 )
{
checkFee=( 0.08*numChecks)+MONTHLY_FEE<<endl;
}
else if (numChecks<60 )
{
checkFee=( 0.06*numChecks)+MONTHLY_FEE<<endl;
}
else (numChecks>60 )
{
checkFee=( 0.04*numChecks)+MONTHLY_FEE<<endl;
}
// Calculate totalFees
if (numChecks<20 && acctBalance<MIN_BAL)
{
totalFees=checkFee+LOW_BAL_FEE<<endl;
}
else if (numChecks<40 && acctBalance<MIN_BAL)
{
totalFees=checkFee+LOW_BAL_FEE<<endl;
}
else if (numChecks<60 && acctBalance<MIN_BAL)
{
totalFees=checkFee+LOW_BAL_FEE<<endl;
}
else if (numChecks>60 && acctBalance<MIN_BAL)
{
totalFees=checkFee+LOW_BAL_FEE<<endl;
}
else (numChecks<20 && acctBalance>MIN_BAL)
{
totalFees=checkFee
}
// Display results: The bank fee
cout<<"The bank fee this month is "<<totalFees<<endl;
}//end the loop
return 0;
}//end
And the errors I'm getting when I try to compile.
Error E2379 lab3.cpp 33: Statement missing ; in function main()
Error E2379 lab3.cpp 36: Statement missing ; in function main()
Warning W8004 lab3.cpp 115: 'transaction' is assigned a value that is never used in function main()
So basically my only problem is already in the title. Can anyone help out? Also I'm new to the C++ language so please be gentle. And if there's any other problems can you point it out to me? Thanks in advance.
You forgot the operators here
cout << "Your beginning balance is: " << acctBalance << endl;
^^
and here
cout << "The number of checks written were: " << numChecks << endl;
^^
Why are you including stdlib.h? I don't see where you are you are using it. If you need this header I'd recommend cstdlib instead.
As already pointed out in the comments you also made a semicolon instead of { which appears a few lines before in your code. Please consider spacing out your operators like this:
if(numChecks < 20) {
}
Using a consistent indention style would also improve readability.

Compare strings using ==

Code, as shown below, can be complied.
Problem: It always says "Invalid Employee id" even when I enter the correct employee id.
Please tell me why and how to do this correctly.
#include <iostream>
#include <iomanip>
using namespace std;
char select, js;
char empid[4];
double bSalary, bonus, tot=0.0;
int main()
{
do
{
cout<<"Employee id: ";
cin>>empid;
if(empid=="M001" || empid=="A004" || empid == "M002") //these are employee ids
{
cout<<"Job Status: ";
cin>>js;
if(js=='P' || js=='C')
{
cout<<"Basic Salary: ";
cin>>bSalary;
if(bSalary>75000 && js=='P')
{
bonus = bSalary*(20.0/100.0);
tot = tot + bonus + bSalary;
}
else if(bSalary>75000 && js=='C')
{
bonus = bSalary*(15.0/100.0);
tot = tot + bonus + bSalary;
}
else
tot = tot+bonus+bSalary;
}
else
cout<<"Invalid Job Status"<<endl;
}
else
cout<<"Invalid Employee no"<<endl;
cout<<"Do you want to continue: ";
cin>>select;
cout<<endl;
}while(select=='y'||select=='Y');
cout<<"Total cost: "<<setprecision(2)<<setiosflags(ios::fixed)<<tot<<endl;
return 0;
}
Note: It is going to the else clause all the time.
It's this:
char empid[4];
This is too small as there's no room for a NUL terminator after the id. You could just change it to 5, but then if someone deliberately or accidentally typed a longer string your program may crash (it's called a buffer overrun, and in some situations can allow whoever provides input to hack the account running the program).
Further, == doesn't work for character arrays: you have to use e.g.:
if (strcmp(empid, "M001") == 0 || strcmp(empid, "A004") == 0 || ...
You would be much better off using a std::string, which will grow to accommodate the actual input (including a NUL terminator though that's not counted in a string's .size()), and works intuitively with ==.
Separately, your...
tot = tot+bonus+bSalary;
...is broken, as bonus may be uninitialised you mustn't read from it in an expression. You can simply remove bonus from the addition above, if it's meant to be 0 for the relevant employees.
You can't compare C strings with == or !=. As you can see that empid here is just a pointer so == will compare the base addresses of those strings not the strings themselves.
You need to use strcmp and include
#include <cstring>
.
.
.
if(strcmp(empid,"M001")==0 || ...)
Empid is not a string. C++ doesn't have a built-in == overload to compare char arrays.
You can make your own == operator. But don't bother. Declare empid as a string and watch magic happen.
string empid;
Changing the size of the char array to take care of NULL char will not work here.
char empid[5]
"==" operator do not work properly with char arrays. please change the condition to below:
if (0 == (strcmp(empid, "M001")) || (0 == (strcmp(empid, "A004"))) || (0 ==
(strcmp(empid, "M002"))))
EDIT:people above has already answered your question. My answer is redundant now.

Using my class member functions practically

I'm trying to make a program that does input/output in the following way, notice that I HAVE NOT finished all of the functions yet. I just need some tips on how to get started because I'm completely stumped on what to do...ANY hints/help would be so appreciated.
Input follows this:
Add Alice
Add Bob
Update Alice laptop 6000 2
Output Alice
Update Bob deskTop 18000 4
Update Bob tabLet 4600 3
Output Bob
Add Charlie
OUTPUT FOR THIS INPUT:
Alice is seller 1.
Bob is seller 2.
Alice sold 2 laptop computers for 6000 Dollars.
Alice: $6000; sold 2 LapTops, 0 DeskTops and 0 Tablets.
Bob sold 4 desktop computers for 18000 Dollars.
Bob sold 3 tablet computers for 4600 Dollars.
Bob: $22600; sold 0 LapTops, 4 DeskTops and 3 Tablets.
Charlie is seller 3.
I really have no idea where to start off now... I need to be able to input the command followed by arguments for the member function parameters...but really have no clue how to incorporate this... this is my second month in C++, so note that I really don't know any advanced things. I have knowledge up to classes....
Main question is just how to use these practically...
Other important info:::: 1. Add – Add command. Add a seller with the given name (Sellername) to the end of the list if a seller with that name doesn't already exist and the list isn't full. The name will be a contiguous sequence of non-white-space characters. Your program doesn't need to check this. See sample outputs.
Output – Output command. Output the total value of computers sold and the total number of each type of computer sold for that seller. If the seller doesn't exist, print an appropriate message. See sample outputs.
Update – Update command. Update the seller with the given sales and the appropriate number of computers. For this command: Sellername designates the name of the sales person; typeOfComputer designates either laptop, desktop or tablet; total-Dollars designates the amount in dollars that was sold; number-of-Computers-Sold designates the quantity of computers of this type that were sold. Your program should convert the typeOfComputer parameter to lower case, as the input will use a mixed case designation. [Hint, include , use function
char tolower(char c); // if c is upper case, returns it in lower case
If the seller doesn't exist, print an appropriate message (and read and discard the data). See sample outputs.
Quit – Quit command. Print out the list of people who sold enough to win the fabulous vacation.
#include <iostream>
#include <cctype>
#include <string>
#include "conio.h"
using namespace std;
const int MAX_SELLERS = 5;
const int NOT_FOUND = -1;
const float GOAL_IN_DOLLARS = 35000.0f;
const int GOAL_IN_COMPUTERS = 12;
class Seller
{
private:
float salestotal; // run total of sales in dollars
int lapTopSold; // running total of lap top computers sold
int deskTopSold; // running total of desk top computers sold
int tabletSold; // running total of tablet computers sold
string name; // name of the seller
public:
// default constructor
Seller()
{
name = "";
salestotal = 0.0;
lapTopSold = 0;
deskTopSold = 0;
tabletSold = 0;
}
// parameterized constructor and member functions
// Constructor:
// Initializes the Seller's name to newname.
// Initializes the Seller's salestotal to 0 and all integer fields to 0.
// Params: in
Seller ( string newname );
// Returns true if the seller's name is the same as nameToSearch;
// false otherwise.
// Params: in
bool SellerHasName ( string nameToSearch );
// Returns true if the seller sold GOAL_IN_COMPUTERS computers
// or GOAL_IN_DOLLARS sales or more.
// Params: NONE
bool WinsPrize ( );
// Adds the money and number of computers to the seller's accumulated
// sales total and number of computers sold based on the computer type.
// That is, if the computer type is “DESKTOP” then the desktop field is
// updated by numComputers, if the computer type is “LAPTOP” then the
// laptop field is updated by numComputers, if the computer type is
// “TABLET” then the tablet fields is updated by numComputers.
// Params: in, in, in
void UpdateSales ( float totalDollars, int numComputers,
string computerType );
// Print the salesperson's name, sales total, and number of
// computers sold.
// Params: NONE
void PrintSales ( );
};
Seller::Seller(string newname)
{
name = newname;
salestotal = 0.0;
lapTopSold = 0;
deskTopSold = 0;
tabletSold = 0;
}
bool Seller::SellerHasName ( string nameToSearch )
{
if(name == nameToSearch)
return true;
else
return false;
}
bool Seller::WinsPrize ( )
{
if(salestotal >= GOAL_IN_DOLLARS || (lapTopSold + deskTopSold +
tabletSold) >= GOAL_IN_COMPUTERS)
return true;
else
return false;
}
void Seller::UpdateSales( float totalDollars, int numComputers,
string computerType )
{
salestotal += totalDollars;
if(computerType == "DESKTOP")
deskTopSold += numComputers;
else if(computerType == "LAPTOP")
lapTopSold += numComputers;
else if(computerType == "TABLET")
tabletSold += numComputers;
}
void Seller::PrintSales ()
{
cout << name << " " << salestotal << "; sold " << lapTopSold <<
"LapTops, " << deskTopSold << " DeskTops, " << "and " <<
tabletSold << " Tablets." << endl;
}
class SellerList
{
private:
int num; // current number of salespeople in the list
Seller salespeople[MAX_SELLERS];
public:
// default constructor to make an empty list
SellerList()
{
num = 0;
}
// member functions
// If a salesperson with thisname is in the SellerList, this
// function returns the associated index; otherwise, return NOT_FOUND.
// Params: in
int Find ( string thisName );
void Add(Seller sellerName);
void Output(Seller sellerName);
};
int SellerList::Find(string thisName)
{
for(int i = 0; i < MAX_SELLERS; i++)
if(salespeople[i].SellerHasName(thisName))
return i;
return NOT_FOUND;
}
// Add a salesperson to the salespeople list IF the list is not full
// and if the list doesn't already contain the same name.
void SellerList::Add(Seller sellerName)
{
Seller(sellerName);
num++;
}
// Output the total value of computers sold and the total number of each
// type of computer sold for that seller. If the seller does not
// exist, print an appropriate message
void SellerList::Output(Seller sellerName)
{
}
int main()
{
return 0;
}
Assuming your Seller implementation is correct and comprehensive (I didn't check it) all you need to do is parse input. In order to parse input, you should read it line by line, interpreting each line as some sort of a command. This command consists of a command name itself along with its arguments (if any).
There are several approaches:
First one:
While end of file isn't reached:
Read a line (string from the current position up to \n symbol)
Split it by spaces. First element of the result is command, rest are arguments. You may need to convert it to appropriate type before executing Seller's method.
Second one:
While end of file isn't reached:
Read a word (from current position up to whitespace symbol).
Now you know the command. If you know the command, you know what arguments should be passed. You can extract them from input right there or delegate it to some other function / method (you pass a reference to input stream to that function and work with that reference)
Take a look at documentation on <iostream> in order to see function's and method's names as well as some examples.