C++ How To Manipulate Output From Game Results? - c++

I just started my C++ class 2 weeks ago at my college and we have our first homework assignments. I'm gonna copy paste the instructions first and then my code to help you understand what my professor is asking for and then show you where I am stuck.
"The program needs to calculate the number of remaining explorers after the battle and the number of extra gold pieces the player keeps after the gold pieces are divided evenly between the surviving explorers (in the above example each of the 4 surviving explorers got 187 gold pieces and the two remaining pieces that couldn't be divided evenly between the 4 explorers go to the player (quest leader))."
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
double numExplorers;
double numLost;
double numSurvived;
double extraGold;
cout << "Welcome to Lost Fortune!" << endl << endl
<< "Please enter the following questions for your personalized adventure: " << endl << endl
<< "Enter the number of Explorers: " << endl;
cin >> numExplorers;
cout << "Enter the number of Explorers Lost in Battle: " << endl << endl;
cin >> numLost;
numSurvived = numExplorers - numLost;
extraGold = 750 / numSurvived;
cout << "You bravely led " << numExplorers << " adventurers on a quest for gold." << endl
<< "The group fought a band of ogres and lost " << numLost << " members." << endl
<< "Only " << numSurvived << " survived." << endl << endl
<< "The party was about to give up when they stumbled upon the" << endl
<< "buried fortune of 750 gold pieces. The group split the loot evenly" << endl
<< "and as the qeust leader you kept the extra " << fixed << setprecision(1) << extraGold << " gold pieces." << endl;
system("PAUSE");
return 0;
}
That is my current code. Our professor has numerous examples we need to plug our program into to test against, but I'll provide one set of the numbers. The number of explorers is 17 and the number lost is 13. That leaves 4 remaining. The 750 pieces (It is always 750 as per professor's instructions for this program) are supposed to be divided amongst the 4 players evenly leaving us with 187.5 per player.
The 0.5 * 4 players leaves us with 2 remaining pieces that can't be evenly distributed and thus we (quest leader) are supposed to keep it. How do I write a formula for this?

Related

C++ Beginner: How do I prevent the text in my table from pushing any text to the right of it?

I am working on a very basic program for my Fundamentals I class and I have everything 98% working as intended.
This program takes the names of three grades, averages them, and outputs them into a table, but since assignmentName[] is on the same line of code as grade[], it pushes grade[] to the right determining on how many characters the user inputted.
Screenshot of the problem
Here is the code I currently have written for the table:
cout << "___________________________\n";
cout << name << "'s Grade Chart\n";
cout << "---------------------------\n";
cout << setprecision(1) << fixed;
cout << "Grade for " << assignmentName[0] << setw(8) << grade[0] << endl;
cout << "Grade for " << assignmentName[1] << setw(8) << grade[1] << endl;
cout << "Grade for " << assignmentName[2] << setw(8) << grade[2] << endl;
cout << "\nYour average grade between those three assignments is: " << setw(1) << avg << endl;`
I commented, "Place another setw(N) where N is a bit bigger than the largest assignmentName before each << assignmentName."
But on second thought it's bit more fun than that, so I figure a real answer is in order.
First, some reading materials:
Documentation on std::left and std::right
Documentation on std::max
And now on with the show!
First we need to know how big the largest assignment name is.
size_t max = 0;
for (const string & assn: assignmentName)
{
max = std::max(max, assn.length());
// You may need
//max = std::max(max, strlen(assn));
// if you've been forced to resort to barbarism and c-style strings
}
max++; // one extra character just in case we get a really long grade.
Sometimes this can get a lot neater. For example std::max_element can eliminate the need for the loop we used to get the maximum assignment name length. In this case we're looking for the size of the string, not the lexical order of the string, so I think the loop and std::max is a bit easier on the brain.
And now to format, we print the names left-justified and the grades right justified, with the names padded max characters and the grades 8 characters.
cout << "Grade for " << std::left << setw(max) << assignmentName[0]
<< std::right << setw(8) << grade[0] << '\n'
<< "Grade for " << std::left << setw(max) << assignmentName[1]
<< std::right << setw(8) << grade[1] << '\n'
<< "Grade for " << std::left << setw(max) << assignmentName[2]
<< std::right << setw(8) << grade[2] << '\n';
Note it's now one big cout. This was done mostly for demonstration purposes and because I think it looks better. It doesn't really save you much, if anything, in processing time. What does save time is the lack of endls. endl is actually a very expensive operation because not only does it end a line, but it also flushes. It forces whatever has been buffered in the stream out to the underlying media, the console in this case. Computers are at their best when they can avoid actually going out of the computer until they really have to. Drawing to the screen is way more expensive than writing to RAM or a cache, so don't do it until you have to.
Instead of writing:
"Grade for " << assignmentName[x] << setw[y] << grade(z)
Write:
"Grade for " << setw[a] << assignmentName[x] << setw[y] << grade(z)
Where a is greater than x in each case.
Maybe that should fix it.
Your a should be something like 10 or 15 or something. I hope it works after that. Try it.

C++ basic converting and then adding up user inputs

This is my attempt at a solution I wrote for an exercise in Bjarne Stroustrup's Programming Principles and C++ book. Unfortunately, the section I wrote to give the total amount of money from the coins entered is not working how I would like!
A quick answer and I would be very grateful but if anyone also has the time could they help me introduce some basic error checking?
The way I would want it to work would be after a user input is required (e.g How many 20p's do you have?), to check whether or not the user inputted an int. If not, provide a subtle error message and a chance to repeat the same question, rather than stop the program or start the program from the beginning!
#include "../../std_lib_facilities.h"
int main() {
int one, ten, twenty, fifty, one_pound, two_pound;
double amount;
amount = (one * 0.01) + (ten * 0.1) + (twenty * 0.2) + (fifty * 0.5) + one_pound + (two_pound * 2);
cout << "Welcome to the change counter app!\nHow many 1p's do you have?\n";
cin >> one;
cout << "How many 10p's do you have?\n";
cin >> ten;
cout << "How many 20p's do you have?\n";
cin >> twenty;
cout << "How many 50p's do you have?\n";
cin >> fifty;
cout << "How many £1 coin's do you have?\n";
cin >> one_pound;
cout << "How many £2 coin's do you have?\n";
cin >> two_pound;
cout << "You have: " << one << " 1p coins!\n"
<< "You have: " << ten << " 2p coins!\n"
<< "You have: " << twenty << " 20p coins!\n"
<< "You have: " << fifty << " 50p coins!\n"
<< "You have: " << one_pound << " £1 coins!\n"
<< "You have: " << two_pound << " £2 coins!\n"
<< "The total amount of money you have is: " << amount << "\n";
}
You have two problems:
The first is that in the absence of loops, code runs from top to bottom. That means you calculate amount before you read the input.
The second problem is that when you calculate amount (currently, in the wrong place) you use the variables one, ten, etc. before they are initialized. Uninitialized local variables will have an indeterminate value, and using them will lead to undefined behavior.
The simple solution to both problems is to move the calculation of amount to after you have read the input, but before you write the output.

How do I align dollar amounts so cents match up in C++?

My program executes just fine, but I was wondering how to align my output so cents line up rather than dollars.
We've only started class a couple weeks ago, so we haven't gone over this yet. My professor says it's okay for now if they don't align, I guess I'm just OCD about it. Plus, I think it looks a lot cleaner.
Also, if the bill is $38.40, would that be four significant figures? Sorry, I haven't taken math in a while. In my output, I'm getting up to five significant figures for some reason. The most I have is four. How would I fix this, using setprecision?
cout << "Bill \t \t $ " << bill << endl;
cout << "Tax at 10.5% \t \t $"<<tax<< endl;
cout << "Sub-total \t \t $"<<subTotal<< endl;
cout << "Tip at 20% \t \t $"<<tip<< endl;
cout << endl;
cout << "Total Bill \t \t \t $"<<totalBill<< endl;
As you see, I've been trying it using the tab escape. As a reply suggests, I should use setw?
Edit for 9/10:
I've gotten all my dollar amounts rounded to two decimals, except for the bill, and I don't know how to fix it. Thanks for all the info you've given me, but it's too advanced for what we're doing right now, so I've just aligned things manually. I still need to add setw and then fix everything once that's there. I'm just asking about why the bill is only three digits. It's probably something super simple that's going right over my head.
// Declare variables
double bill, tax, subTotal, tip, totalBill;
// Variables
bill = 38.40;
tax = .105;
tip = .20;
// Calculate the tax
tax = bill * .105;
// Calculate sub-total of bill
subTotal = bill + tax;
// Calculate tip
tip = subTotal * .20;
// Calculate total amount of bill
totalBill = subTotal + tip;
cout << "Bill" " $ " << setprecision(4) << bill << endl;
cout << "Tax at 10.5%" " $ " << setprecision(3) << tax << endl;
cout << "Sub-total" " $ " << setprecision(4) << subTotal << endl;
cout << "Tip at 20%" " $ " << setprecision(3) << tip << endl;
cout << endl;
cout << "Total Bill" " $ " << setprecision(4) << totalBill << endl;
Edit: I "fixed" it. All is good now.
If you're printing money, I recommend you look at C++'s money I/O.
std::put_money will ensure you are international compliant and printing with correct rounding/precision.
Set the locale of std::cout for USD.
std::showbase will decide whether to print the $.
//settings for printing as USD
std::cout.imbue(std::locale("en_US.utf8"));
std::cout << std::showbase;
Use std::setw and std::left for formatting.
Here is an example of printing your data:
#include <iostream>
#include <string>
#include <iomanip>
//row data from example
struct Row{
std::string description;
float amount;
};
//function for printing a row
void Print(Row row);
int main(){
//example rows
Row a{"Bill",3840};
Row b{"Tax at 10.5%",403};
Row c{"Sub-total",4243};
Row d{"Tip at 20%",848};
Row e{"Total Bill",5091};
//settings for printing as USD
std::cout.imbue(std::locale("en_US.utf8"));
std::cout << std::showbase;
//format printing
Print(a);
Print(b);
Print(c);
Print(d);
std::cout << '\n';
Print(e);
}
void Print(Row row){
static const int COLUMN_WIDTH{14};
std::cout << std::setw(COLUMN_WIDTH) << std::left << row.description;
std::cout << " " << std::right << std::put_money(row.amount) << '\n';
}
result:
Bill $38.40
Tax at 10.5% $4.03
Sub-total $42.43
Tip at 20% $8.48
Total Bill $50.91
One possible way is to use setw.
cout<<setw(5)<<4.55<<endl;
cout<<setw(5)<<44.55<<endl;
output:
4.55
44.55
Update:
as Jonathan Leffler pointed out, the << operator resets the width, hence the code is updated to show it should be repeated.
I would do something like:
std::cout << std::setw(15) << std::left << "Bill";
std::cout << std::setw(15) << std::right << std::fixed << std::setprecision(2) << bill << std::endl;
std::cout << std::setw(15) << std::left << "Tax # 10.5%";
std::cout << std::setw(15) << std::right << std::fixed << std::setprecision(2) << tax << std::endl;
This sets the width of the output for each "column" to 15 characters so you don't have to rely on tabs. All of the the "labels" will be left justified, and all of the prices will be right justified and printed to 2 decimal places. This is a bit more robust than relying on tabs, where you don't have control as to how many characters are used. You can't do proper justification with tabs.

I am having issues with string concatenation [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am using orwell dev| c++
C++ is a new language to, i am coming from c# which is like i would say 70% the same.
here is my code
#include<iostream>
#include<fstream>
using namespace std;
///loading libraries
float const taxnet = .9;
float const taxwh = .1;
int employeenumber;
float payrate, gross, net, manhours, overtime, taxes;
///declaring variablies and costants
char more;
char more2;
///user controls
///payroll calculations function
void payrollcalc () {
if (manhours>40) {
overtime= manhours-40;
gross= ((manhours - overtime) * payrate)+((payrate * 1.5)* overtime);
//overtime claculation
}
else {
gross =manhours * payrate;
//no overtime calculation
}
taxes= gross * taxwh;
net = gross * taxnet;
//taxesand net pay calculation
cout<< " Your ID is " << employeenumber <<endl;
cout<< " # of hours worked " << manhours << endl;
cout<< " Your Hourly rate is " << payrate << endl;
cout<< " Your Gross pay is " << gross << endl;
cout<< " Your tax rate is " << taxwh << endl;
cout<< " Amount of taxes " << taxes << endl;
cout<< " Your net pay is " << net << endl;
///writing to file
std::string empnum = std::to_string(employeenumber);
ofstream payroll;
payroll.open (empnum+".txt");
payroll<< " Your ID is " << employeenumber <<endl;
payroll<< " # of hours worked " << manhours << endl;
payroll<< " Your Hourly rate is " << payrate << endl;
payroll<< " Your Gross pay is " << gross << endl;
payroll<< " Your tax rate is " << taxwh << endl;
payroll<< " Amount of taxes " << taxes << endl;
payroll<< " Your net pay is " << net << endl;
payroll.close();
}
main(){
while (more != 27){
//main
cout<< "Hit 1 to enter data hit 2 to recall dat hit esc to exit";
///instructions
newdata:
///call back see line 115
if (more == 49) {
cout<< "Enter Employee ID:";
cin>> employeenumber;
cout<<"Enter Number of Hours Worked:";
cin>> manhours;
cout<<"Enter Pay rate:";
cin>> payrate;
cin>> payrollcalc;
}
else (more == 50) {
olddata:
///call back see line 111
errorreset:
cout<< "Enter employee number";
cin>> employeenumber;
///reading in data
ifstream payroll = employeenumber;
payroll.open(employeenumber".txt");
if (!payroll){
cout>> "Check employeenumber and try agian" endl;
goto errorreset:
///error check
}
cout>> payroll.eof endl;
cout>> endl;
cout>> endl;
cout>> "Press Enter to see another employee number; Press space to enter new employee information; press escape to exit the program" endl;
if (more2 == 13 ){
goto olddata;
}
else (more2 == 32){
goto newdata;
}
///sending back to the loop
}
//entering data
return 0;
}
}
I think my issues is in this segment
std::string empnum = std::to_string(employeenumber);
ofstream payroll;
payroll.open (empnum+".txt");
payroll<< " Your ID is " << employeenumber <<endl;
payroll<< " # of hours worked " << manhours << endl;
payroll<< " Your Hourly rate is " << payrate << endl;
payroll<< " Your Gross pay is " << gross << endl;
payroll<< " Your tax rate is " << taxwh << endl;
payroll<< " Amount of taxes " << taxes << endl;
payroll<< " Your net pay is " << net << endl;
payroll.close();
If some can step me through where i am going off the rails i would be grateful because i am out of ideas.
First off consider turning up the error/waring level of your compiler, for gcc/clang a sensible level would be -Wall -Wextra for a start.
Let me go through some of the problems I see in your code.
main(){
We got a first problem here already. The only 2 signatures allowed for the main function in C++ are int main() or int main(int argc, char *argv[]). Yours might be accepted due to legacy reasons (implicit return type of int in C if you don't specify any) but shouldn't be used.
cout>> payroll.eof endl; // this line absolutely makes no sens and you forgot some `<<` in here probably.
cout>> endl;
cout>> endl;
cout>> "Press Enter to see another employee number; Press space to enter new employee information; press escape to exit the program" endl;
The 'arrows' point into the wrong direction. It should be cout << endl. To remember it see them as arrows that signify the data flow. cin >> variable the data is read from cin and gets put into the variable, cout << variable the variable gets output into cout.
Then you got a read that doesn't make sense:
cin>> payrollcalc;
payrollcalc is a function, I don't know what you wanted to do here, but you should probably call it like payrollcalc();, trying to read from cin into it doesn't make sense.
You're also using std::string without #include <string>. Also note that you should probably put a space in the include line like I did. I don't know if it's a problem without space of the top of my head but it's certainly more readable with a space.
Now for some bad practices and other stuff that I should probably point out. Your indentation and formatting were very messy and made it hard to spot anything you should probably see into cleaning it up a bit.
As for goto it's considered bad practice/harmful. This was started by Dijkstra. Now to say it got it's uses still in some places and is often over exaggerated but for the simple code you're using I don't think it's necessary and could probably be done in a better more structured way that makes the logic easier to understand, remember code is read far more often than you write it and readability is very important. If you're curious about the problems, #itsnotmyrealname posted a link on your question already for you to look through.
Also you got inconsistencies that make it harder to read/confusing.
gross =manhours * payrate; // inconsistent assignments
taxes= gross * taxwh;
net = gross * taxnet;
std::to_string(employeenumber) // inconsistent function calls.
payroll.open (empnum+".txt");
As for the global variables if you've already got some experience in programming (in C# like you said) then you probably know that they are considered bad practice too and should be avoided, you should look into making them local variables and passing them around as function arguments/returning them from functions.

How to account for ties in test scores when your finding out lowest and highest scores from from 3 test scores?

For my C++ assignment I have to find Lowest, highest, and average of test scores from a set of three test scores. What extra code do i need in case Two or all three have the same test score when finding the highest and lowest test score in C++? Here is the code i have so far it runs fine except for if two of the scores are the same.
#include <iostream>
using namespace std;
int main()
{
int _midtermgrade, _projectaverage, _homeworkaverage, average;
cout << " Please enter your midterm grade:" << endl;
cin >> _midtermgrade;
cout << "Please enter your project average:" << endl;
cin >> _projectaverage;
cout << " Please enter your homework average:" << endl;
cin >> _homeworkaverage;
if((_midtermgrade >_projectaverage)&&(_midtermgrade >_homeworkaverage)){
cout << "Your highest score is your midterm " << _midtermgrade endl;
}
if ((_projectaverage >_midtermgrade)&(_projectaverage>_homeworkaverage))
cout << "Your highest score is your project " << _projectaverage << endl;
}
if((_homeworkaverage >_projectaverage&(_homeworkaverage>_midtermgrade)){
cout << "Your highest score is your homework "<< _homeworkaverage <<endl;
}
if((_midtermgrade < _projectaverage)&&(_midtermgrade<_homeworkaverage)){
cout << "Your lowest score is your midterm " << _midtermgrade<< endl;
}
if((_projectaverage<_midtermgrade)&&(_projectaverage<_homeworkaverage)){
cout << "Your lowest score is your project "<< _projectaverage<<endl;
}
if ((_homeworkaverage<_projectaverage)&&_midtermgrade)){
cout
<< "Your lowest score is your homework " << _homeworkaverage << endl;
}
average =((_midtermgrade * 20 +_projectaverage* 40 + _homeworkaverage*15)
/ (20 + 40 + 15));
cout << "Your currentaverage is " << average <<endl;
if (_midtermgrade < 70){
cout << "You have a failing grade on the midterm." << endl;
}
else
cout << "You have a passing grade on the midterm." << endl;
if (_projectaverage < 70){
cout << "You have a failing grade on the project." << endl;}
else
cout << "You have a passing grade on the project." << endl;
if (_homeworkaverage < 70){
cout << "You have a failing grade on the homework." << endl;
} else
cout << "You have a passing grade on the homework." << endl;
return 0;
}
From a first glance at your code, I could tell right away that you're doing too much work. You should be using functions and function calls to make your code more modular. This will reduce code bloat, make your code easier to read/follow and make your code easier to maintain if you ever want to add/change something to it in the future.
For instance, you could create both a min and max function to find the highest and lowest test scores.
For example...
int MAX(int test_score1, int test_score2, int test_score3)
{
if(conditional statement)
return something;
}
After you implement your min and max functions, create another function to find the average test score in the same way.
As for your original question, if you have two or three test scores which are the same, then the simplest approach would be to use the logical operator == to test for equality between all three test scores. All you have to figure out is where in your control flow (program) do you want to test equality of all three test scores.
To learn more about functions see this C++ online tutorial page. If this answer solved your problem, don't forget to click the checkmark on the left. Otherwise, if you have more questions, feel free to leave me a comment and I will try to help you out.