C++ code works, but seems very inefficient - c++

I'm currently learning C++ and got my code to do everything I want it to but it seems as if the code is not very efficient because I basically doubled the code from my output console so it shows up in a text file. If you can, could you explain what I am doing wrong and what would you suggest I do in order to make the code more efficient. (Also column one needs to be left justify and column two has to be right justify in both console and text file which I believe I did correctly.)
/* Description: This program calculates and prints the monthly paycheck for an employee (Output in command prompt and .txt file).*/
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
using namespace std;
char name[256];
double gross;
double fiTax;
double sTax;
double ssTax;
double mediTax;
double pPlan;
double hInsurance;
double tax;
double total;
int main() {
std::cout << "Please enter your name: ";
std::cin.getline(name, 256);
cout << "Please enter your gross amount: ";
cin >> gross;
std::cout << std::fixed;
std::cout << std::setprecision(2);
fiTax = gross * .15;
sTax = gross * .035;
ssTax = gross * .0575;
mediTax = gross * .0275;
pPlan = gross * .05;
hInsurance = 75;
tax = fiTax + sTax + ssTax + mediTax + pPlan + hInsurance;
total = gross - tax;
system("cls");
ofstream file;
file << std::fixed << std::setprecision(2);
file.open("report.txt");
cout << left<< setw(28) << name << endl;
file << left << setw(28) << name << endl;
cout << left << setw(28) << "Gross Amount: ............ $";
cout << right << setw(7) << gross << endl;
file << left << setw(28) << "Gross Amount: ............ $";
file << right << setw(7) << gross << endl;
cout << left << setw(28) << "Federal Tax: ............. $";
cout << right << setw(7) << fiTax << endl;
file << left << setw(28) << "Federal Tax: ............. $";
file << right << setw(7) << fiTax << endl;
cout << left << setw(28) << "State Tax: ............... $";
cout << right << setw(7) << sTax << endl;
file << left << setw(28) << "State Tax: ............... $";
file << right << setw(7) << sTax << endl;
cout << left << setw(28) << "Social Security Tax: ..... $";
cout << right << setw(7) << ssTax << endl;
file << left << setw(28) << "Social Security Tax: ..... $";
file << right << setw(7) << ssTax << endl;
cout << left << setw(28) << "Medicare/medicaid Tax: ... $";
cout << right << setw(7) << mediTax << endl;
file << left << setw(28) << "Medicare/medicaid Tax: ... $";
file << right << setw(7) << mediTax << endl;
cout << left << setw(28) << "Pension Plan: ............ $";
cout << right << setw(7) << pPlan << endl;
file << left << setw(28) << "Pension Plan: ............ $";
file << right << setw(7) << pPlan << endl;
cout << left << setw(28) << "Health Insurance: ........ $";
cout << right << setw(7) << hInsurance << endl;
file << left << setw(28) << "Health Insurance: ........ $";
file << right << setw(7) << hInsurance << endl;
cout << left << setw(28) << "Net Pay: ................. $";
cout << right << setw(7) << total << endl;
file << left << setw(28) << "Net Pay: ................. $";
file << right << setw(7) << total << endl;
file.close();
return 0;
}

Your suspicions of inefficiency are completely unwarranted and irrelevant. Such a trivial, I/O bound code has absolutely no need for optimization, and if you write the whole I/O subsystem from scratch, any performance gain will be negligible and meaningless.
You don't have a target efficiency metric, or any efficiency measurements. In other words, you neither know how fast (or slow) your code is, nor how fast it should be. Without measurements and targets, all optimization is useless (or at best, very wasteful.)
Your code could look better. Whether the extra empty lines was your work or a side-effect of pasting the code here, you just never bothered to remove them. You should keep in mind that the appearance of your code matters. (Update: I see that you've fixed this. Kudos!)
Please don't use global variables, unless you have some experience and you judge that you do need them. In this case, you don't. If you changed you variables' scopes to local, remember to initialize them as well.
Don't use char arrays to represent strings. Use std::strings. They have all the array functionality and much more, and are much safer and much more convenient.
One way to save yourself some typing/copy+pasting and eliminate some redundancy in your code (which is very bad) is to use the parent class of both the std::cout object's type and the std::ofstream type which is std::ostream. You can write functions that take an object of this type as a parameter and only once write out what you want to write out, then you will call these functions twice: once with std::cout and once with your file.
All these points aside, I hope you'll remember this: don't worry about performance and optimization unless you can objectively prove that it's a problem.
(Sorry about the tone of this response; the OP said he is a beginner and that put me in a lecturing mood!)
Update: You can write a function like this:
void LineOut (std::ostream & os, std::string const & entry, double value)
{
int dots = 28 - 2 - int(entry.size()); // 2 for ": "
if (dots < 0) dots = 0;
os << entry << ": " << std::string('.', dots) << "$" << value << std::endl;
}
// Call it like this:
LineOut(std::cout, "Gross Amount", gross);
LineOut( file, "Gross Amount", gross);
Now you'll call this function twice for each line of output: once for cout and once for your file.
There are obviously other ways, and better ways, but I doubt that they are worth it for this small a project.

You could write a function which will print the values in file and output.
void WriteToFileAndOutput(const double &val, const string &s, ofstream &fname) {
cout << left << setw(28) << s;
cout << right << setw(7) << val << endl;
fname << left << setw(28) << s;
fname << right << setw(7) << val << endl;
}
//You can use it as
WriteToFileAndOutput(gross, "Gross Amount: ............ $", file);
WriteToFileAndOutput(fiTax, "Federal Tax: ............. $", file);
C++ has built-in string datatype, use it instead of char arrays.
If you have included using namespace std then you don't have to specify again that cout, cin etc are from std namespace.
Do not use global variables.
Just for example:
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
using namespace std;
void WriteToFileAndOutput(const double &val, const string &s, ofstream &fname) {
cout << left << setw(28) << s;
cout << right << setw(7) << val << endl;
fname << left << setw(28) << s;
fname << right << setw(7) << val << endl;
}
int main() {
string name;
double gross, fiTax, sTax, ssTax, mediTax, pPlan, hInsurance, tax, total;
cout << "Please enter your name: ";
getline(cin,name);
cout << "Please enter your gross amount: ";
cin >> gross;
cout << fixed;
cout << setprecision(2);
fiTax = gross * .15;
sTax = gross * .035;
ssTax = gross * .0575;
mediTax = gross * .0275;
pPlan = gross * .05;
hInsurance = 75;
tax = fiTax + sTax + ssTax + mediTax + pPlan + hInsurance;
total = gross - tax;
ofstream file;
file << fixed << setprecision(2);
file.open("report.txt");
cout << left << setw(28) << name << endl;
file << left << setw(28) << name << endl;
WriteToFileAndOutput(gross, "Gross Amount: ............ $", file);
WriteToFileAndOutput(fiTax, "Federal Tax: ............. $", file);
WriteToFileAndOutput(sTax, "State Tax: ............... $", file);
WriteToFileAndOutput(ssTax, "Social Security Tax: ..... $", file);
WriteToFileAndOutput(mediTax, "Medicare/medicaid Tax: ... $", file);
WriteToFileAndOutput(pPlan, "Pension Plan: ............ $", file);
WriteToFileAndOutput(hInsurance, "Health Insurance: ........ $", file);
WriteToFileAndOutput(total, "Net Pay: ................. $", file);
file.close();
return 0;
}

One way you can reduce the redundancy in your code is to create a function to do the printing. The C++ output stream classes are all subclasses of std::ostream. This means you can write a function that accepts std::ostream& (reference to std::ostream) and pass it any output stream like std::cout or an std::ofstream.
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
using namespace std;
char name[256];
double gross;
double fiTax;
double sTax;
double ssTax;
double mediTax;
double pPlan;
double hInsurance;
double tax;
double total;
// function prints info to any std::ostream
void print_to(std::ostream& out)
{
out << left<< setw(28) << name << endl;
out << left << setw(28) << "Gross Amount: ............ $";
out << right << setw(7) << gross << endl;
out << left << setw(28) << "Federal Tax: ............. $";
out << right << setw(7) << fiTax << endl;
out << left << setw(28) << "State Tax: ............... $";
out << right << setw(7) << sTax << endl;
out << left << setw(28) << "Social Security Tax: ..... $";
out << right << setw(7) << ssTax << endl;
out << left << setw(28) << "Medicare/medicaid Tax: ... $";
out << right << setw(7) << mediTax << endl;
out << left << setw(28) << "Pension Plan: ............ $";
out << right << setw(7) << pPlan << endl;
out << left << setw(28) << "Health Insurance: ........ $";
out << right << setw(7) << hInsurance << endl;
out << left << setw(28) << "Net Pay: ................. $";
out << right << setw(7) << total << endl;
}
int main() {
std::cout << "Please enter your name: ";
std::cin.getline(name, 256);
cout << "Please enter your gross amount: ";
cin >> gross;
std::cout << std::fixed;
std::cout << std::setprecision(2);
fiTax = gross * .15;
sTax = gross * .035;
ssTax = gross * .0575;
mediTax = gross * .0275;
pPlan = gross * .05;
hInsurance = 75;
tax = fiTax + sTax + ssTax + mediTax + pPlan + hInsurance;
total = gross - tax;
system("cls");
// an std::ofstream is a sub-class of std::ostream
ofstream file;
file << std::fixed << std::setprecision(2);
file.open("report.txt");
print_to(file);
file.close();
// an std::cout is a sub-class of std::ostream
print_to(std::cout);
return 0;
}

Related

I am having trouble with using getline

I am having trouble with my code not reading the whole string name.
I have tried using getline(cin, movieName) as well as cin.ignore(), but I can't get it to work properly.
I am taking a beginner's course to this class, but my professor does not answer their emails.
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
string movieName;
const float adultTicketPrice = 12;
const float childTicketPrice = 6;
const float percentTheaterKeeps = .20;
int adultTicketsSold, childTicketsSold;
float grossProfit, netProfit, amountPaidToDistributor;
getline(cin, movieName);
cout << fixed << showpoint << setprecision(2);
cout << "What movie played tonight?\t ";
cin >> movieName;
cout << "How many adult tickets were sold? ";
cin >> adultTicketsSold;
cout << "How many child tickets were sold? ";
cin >> childTicketsSold;
grossProfit = adultTicketPrice * adultTicketsSold + childTicketPrice * childTicketsSold;
netProfit = grossProfit * percentTheaterKeeps;
amountPaidToDistributor = grossProfit - netProfit;
cout << setw(10) << left << "Movie Name";
cout << setw(23) << right << movieName << endl;
cout << setw(10) << left << "Adult Tickets Sold";
cout << setw(16) << right << adultTicketsSold << endl;
cout << setw(10) << left << "Child tickets sold";
cout << setw(16) << right << childTicketsSold << endl;
cout << setw(10) << left << "Gross Box Office Profit";
cout << setw(11) << right << grossProfit << endl;
cout << setw(10) << left << "Net Box Office Profit";
cout << setw(13) << right << netProfit << endl;
cout << setw(10) << left << "Amount Paid to distributor";
cout << setw(8) << right << amountPaidToDistributor << endl << endl;
return 0;
}
You need to use std::getline(std::cin, movieName) when you want to get input for movieName.
Presumably you're seeing a blank line when you start your program, and pressing enter. This sets movieName to '\n'. Remove that line, and switch std::cin >> movieName; with std::getline(std::cin, movieName). (Remove the std::s if you're using a using declaration)

Having issues with mathematical calculations and setprecision() function

I seem to be having a problem with a C++ coding question. It involves mathematical arithmetic and I seem to be getting all of my outputs correct except the final one. In addition to this, the decimal point format of my answers seem to be incorrect. The answers should contain two decimal places but only two out of my four decimal point answers seem to have two decimal places. When I try to use the precision() function, the answers go into scientific notation which I do not want.
Here is the question and answer:
Here is my code:
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main()
{
float principal;
float interest_rate;
float times_compounded;
cout << "Hello, please enter a value for your principal: ";
cin >> principal;
cout << principal << endl;
cout << "Please enter a value for your interest rate: ";
cin >> interest_rate;
cout << interest_rate << "%" << endl;
cout << "Please enter the number of times the interest is compounded during the year: ";
cin >> times_compounded;
cout << times_compounded << endl << endl;
float interest = interest_rate * 10.197647;
float amount = principal * pow((1 + (interest_rate/times_compounded)), times_compounded);
cout << "Interest Rate: " << setw(19) << interest_rate << "%" << endl;
cout << "Times Compounded: " << setw(17) << times_compounded << endl;
cout << "Principal: " << setw(17) << "$ " << setw(7) << principal << endl;
cout << "Interest: " << setw(20) << "$ " << interest << endl;
cout << "Amount in Savings: " << setw(9) << "$ " << amount;
return 0;
}
Here are my three inputs:
1000, 4.25, 12
Any feedback would be appreciated, thank you for your time.
First, the last value is wrong because you're using the interest rate as a normal number in the formula although it's actually a percentage. So you'd need to divide it by 100:
float amount = principal * pow((1 + ((interest_rate / 100) /times_compounded)), times_compounded);
Now for the precision, you can use std::fixed in conjunction with std::setprecision to set the default floating point printing precision when using std::cout. We can use a macro to make it more readable, like:
#define FIXED_FLOAT(x, p) std::fixed<<std::setprecision(p)<<(x)
So, the full output section would look like:
cout << "Interest Rate: " << setw(19) << FIXED_FLOAT(interest_rate, 2) << "%" << endl;
cout << "Times Compounded: " << setw(17) << FIXED_FLOAT(times_compounded, 0) << endl;
cout << "Principal: " << setw(17) << "$ " << setw(7) << FIXED_FLOAT(principal, 2) << endl;
cout << "Interest: " << setw(20) << "$ " << FIXED_FLOAT(interest, 2) << endl;
cout << "Amount in Savings: " << setw(9) << "$ " << FIXED_FLOAT(amount, 2);
Also, that interest = interest_rate * 10.197647 seems fishy. Interest should just be the amount minus the principal.

recite and tip output alignment C++, output formatting

I'm writing this code for my programming class and I got everything else to work however my output formatting isn't working out for me.
#include <iostream>
#include <iomanip>
#include <ios>
using namespace std;
int main()
{
double tip_fifteen;
double tip_twenty;
double tax;
double bill;
char dollars = '$';
float meal_cost;
cout << "Enter the meal cost: ";
cin >> meal_cost;
tip_twenty = meal_cost * .20;
tip_fifteen = meal_cost * .15;
tax = meal_cost * 0.0975;
cout << "******************************************" << endl;
//beginning outputs
int digits;
digits = meal_cost * 100 / 100;
cout << setw(10) << left << "Meal Cost " << dollars;
cout << setw(to_string(digits).length() + 3) << fixed << showpoint << setprecision(2) << meal_cost << endl;
cout << setw(10) << left << "Tax " << dollars;
cout << setw(to_string(digits).length() + 3) << fixed << showpoint << setprecision(2) << tax << endl;
cout << setw(10) << left << "Tip (15%) " << dollars;
cout << setw(to_string(digits).length() + 3) << fixed << showpoint << setprecision(2) << tip_fifteen << endl;
//tip outputs then final output statements
cout << setw(10) << left << fixed << setprecision(2) << "Tip (20%) " << dollars << tip_twenty << endl;
bill = tip_fifteen + meal_cost + tax;
cout << "Your total bill is " << fixed << setprecision(2) << dollars << bill << " after 15% gratuity." << endl << "or" << endl;
bill = tip_twenty + meal_cost + tax;
cout << "Your total bill is " << fixed << setprecision(2) << dollars << bill << " after 20% gratuity." << endl;
return 0;
I want my output to look like this
Enter the meal cost: 56
******************************************
Meal Cost $ 56.00
Tax $ 5.46
Tip (15%) $ 8.40
Tip (20%) $ 11.20
Your total bill is 69.86 after 15% gratuity.
or
Your total bill is 72.66 after 20% gratuity.
my output looks like this
Enter the meal cost: 56
******************************************
Meal Cost $56.00
Tax $5.46
Tip (15%) $8.40
Tip (20%) $11.20
Your total bill is $69.86 after 15% gratuity.
or
Your total bill is $72.66 after 20% gratuity.
I'm having a problem using setw with floats however it's not working when i try to set the same variable as an int.
I've also tried using setw(25) to see if that would work somehow unfortunately it has not
You need to use right if you want them aligned to the right, you also need to add a space " " after the dollars
cout << setw(10) << left << "Meal Cost " << dollars << " ";
cout << setw(to_string(digits).length() + 3) << fixed << right << showpoint << setprecision(2) << meal_cost << endl;
To this to all of the printed statements and you will get:
******************************************
Meal Cost $ 56.00
Tax $ 5.46
Tip (15%) $ 8.40
Tip (20%) $ 11.20
For there to be padding in the price column, setw has to be set to a large enough width.
For example:
std::cout << "$" << std::setw(10) << std::fixed
<< std::setprecision(2) << 56.0f << std::endl;
Prints:
$ 56.00
Your code sets the width to:
std::to_string(digits).length() + 3
Which is only 5 characters, just enough to fit "56.00". For additional padding on the left you should increase the setw width.

Displaying output to the right

So i am very new to programming and C++. This little simple program is my second one and I'm in need of a little assistance. Below is my code followed by the output that I am getting and what I want it to look like. If anyone can point me in the right direction, or let me know how to change this it would be much appreciated.
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
int main()
{
double propValue, //Property Value
assessment, //Assessment
srAssessment, //Sr Assessment
taxRate, //Tax rate
annualPropTax, //Annual Property tax
quarterlyTax; //Quarterly Tax
string name;
const double EXEMPT = 5000, //shows the total after exemption
QUARTER = 4, //represents the amount of quarters in a year
TAXPERHUNDRED = 0.01, //represents tax rate for every $100
SIXTYPERCENT = 0.6; //Represents the tax based on 60% of original value
//Gets name from user
cout << "Please enter your full name: ";
getline(cin, name);
//gets property value from user
cout << "Enter the actual value of the property: ";
cin >> propValue;
//Gets tax rate
cout << "Enter the tax rate for each $100 of assessed value: ";
cin >> taxRate;
cout << endl << endl;
//Calculates assessment
assessment = propValue * SIXTYPERCENT;
//Calculates Sr. Assessment
srAssessment = assessment - EXEMPT;
//Calculates annual property tax
annualPropTax = srAssessment * taxRate * TAXPERHUNDRED;
//Calculates Quarterly tax
quarterlyTax = annualPropTax / QUARTER;
//Displays owners name
cout << "Property owner's name: " << name << endl;
cout << endl;
cout << setprecision(2) << fixed;
//Displays Assesment
cout << "Assessment: " << setw(18) << "$ " << srAssessment << endl;
//Displays Annual Property tax
cout << "Annual Property Tax" << setw(11) << "$ " << std::right << annualPropTax << endl;
//Displays Quarterly Property tax
cout << "Quarterly Property Tax" << setw(8) << "$ " << std::left << quarterlyTax;
cout << endl << endl;
}
This is the current output:
Assessment: $ 175000.00
Annual Property Tax $ 7177.50
Quarterly Property Tax $ 1780.63
What I need it to do is display as so:
Assessment: $ 175000.00
Annual Property Tax $ 7177.50
Quarterly Property Tax $ 1780.63
I guess it should be intutive. Add setw to second print also:
cout << "Assessment: " << setw(18) << "$ " << setw(10) << std::right << srAssessment << endl;
// ^^^^^^^^^^^^^^^^^^^^^^^^^
cout << "Annual Property Tax" << setw(11) << "$ " << setw(10) << std::right << annualPropTax << endl;
// ^^^^^^^^^^^
cout << "Quarterly Property Tax" << setw(8) << "$ " << setw(10) << std::right << quarterlyTax;
// ^^^^^^^^^^^^^^^^^^^^^^^^^
Add right in your cout statement
Here is another stack overflow post related:
Right Justifying output stream in C++
std::cout << std::right << std::setw(x) << "output";
Where x is an integer to represent the width of the following "output".

How do I properly format C++ floats to two decimal places?

I'm having some issues using setprecision. I don't understand how it works completely. I searched the problem and was able to extrapolate some code that should've worked. I don't understand why it's not. Thank you for your help, I'm still kind of new at this.
//monthly paycheck.cpp
//Paycheck Calculator
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main() {
//Constants
const double
FEDERAL_TAX = 0.15, //Federal Tax
STATE_TAX = 0.035, //State Tax
SSA_TAX = 0.085, //Social Security & Medicare
HEALTH_INSURANCE = 75; //Health Insurance
//Variables
int year;
double grossAmount;
string employeeName, month;
// Initialize variables with input
cout << "Hello, what's your first name? ";
cin >> employeeName;
cout << "What is your gross amount? ";
cin >> grossAmount;
cout << "Please enter the month and year: ";
cin >> month >> year;
// Output
cout << "***********************************" << endl;
cout << "Paycheck" << endl;
cout << "Month: " << month << "\tYear: " << year << endl;
cout << "Employee Name: " << employeeName << endl;
cout << "***********************************" << endl;
cout << setprecision(5) << fixed;
cout << "Gross Amount: $" << grossAmount << endl;
cout << "Federal Tax: $" << FEDERAL_TAX*grossAmount << endl;
cout << "State Tax: $" << STATE_TAX*grossAmount << endl;
cout << "Social Sec / Medicare: $" << SSA_TAX*grossAmount << endl;
cout << "Health Insurance: $" << HEALTH_INSURANCE << endl << endl;
cout << "Net Amount: $" << fixed << grossAmount-grossAmount*(FEDERAL_TAX+STATE_TAX+SSA_TAX)-HEALTH_INSURANCE << endl << endl;
system("PAUSE");
return 0;
}
If you want to format floats to display with 2 decimal places in C++ streams, you could easily:
float a = 5.1258f;
std::cout << std::fixed << std::setprecision(2) << a << std::endl;
See std::fixed and std::setprecision
Use stream manipulators:
std::cout.fixed;
std::cout.precision(Number_of_digits_after_the_decimal_point);