Divider in a program - c++

I am trying to get a divider in my program, I got it to output however I notice their is a gap on the top. For example my code outputs:
*******************************************************************************************
Broome
CST 113 Y01
LAB
Stan
******************************************************************************************
I just want the code to output like this:
*******************************************************************************************
Broome
CST 113 Y01
LAB
Stan
******************************************************************************************
without that annoying gap. Here is my that outputs the divider:
//Output the divider to the screen
cout << setfill('*') << setw(SCREEN_WIDTH + 1) << " " << setfill(' ')
<< endl;
// Output the course heading to the screen
cout << setw((SCREEN_WIDTH + 11) / 2) << COLLEGE << endl;
cout << setw((SCREEN_WIDTH + 11) / 2) << COURSE << endl;
cout << setw((SCREEN_WIDTH + 5) / 2) << LAB_NAME << endl;
cout << setw((SCREEN_WIDTH + 15) / 2) << PROGRAMMER_NAME << endl;
//Output the divider to the screen
cout << setfill('*') << setw(SCREEN_WIDTH + 1) << " " << setfill(' ') << endl;
I am sure it is something simple I am missing

I duplicated your problem using MinGW and running in a 80 column Windows console with SCREEN_WIDTH set to 80. If the console is wider than SCREEN_WIDTH + 1, the problem is not exhibited.
Your code will print exactly SCREEN_WIDTH asterisks followed by a space. If your console is exactly SCREEN_WIDTH columns wide, that space will actually be printed on the next line (though you can't see it -- it's a space!). Even if you subtract one, the space will still be on the last column of the line, causing the cursor to drop a line. The endl will do that again.
I was able to get results very close to what you're looking for with this:
cout << setfill('*') << setw(SCREEN_WIDTH) << "\n" << setfill(' ');
It's one asterisk short of a full line, but that's about the best you can do. If you know you will always run on the same console type with exactly SCREEN_WIDTH columns, you could use empty quotes instead of the "\n". But that's assuming a lot of the console.
Resulting code I used:
#include <iostream>
#include <iomanip>
using namespace std; // BLECH!!
int main()
{
const auto SCREEN_WIDTH = 80;
const auto COLLEGE = "Broome";
const auto COURSE = "CST 113 Y01";
const auto LAB_NAME = "LAB";
const auto PROGRAMMER_NAME = "Stan";
//Output the divider to the screen
cout << setfill('*') << setw(SCREEN_WIDTH) << "\n" << setfill(' ');
// Output the course heading to the screen
cout << setw((SCREEN_WIDTH + 11) / 2) << COLLEGE << endl;
cout << setw((SCREEN_WIDTH + 11) / 2) << COURSE << endl;
cout << setw((SCREEN_WIDTH + 5) / 2) << LAB_NAME << endl;
cout << setw((SCREEN_WIDTH + 15) / 2) << PROGRAMMER_NAME << endl;
//Output the divider to the screen
cout << setfill('*') << setw(SCREEN_WIDTH) << "\n" << setfill(' ');
}
Output:
*******************************************************************************
Broome
CST 113 Y01
LAB
Stan
*******************************************************************************

Related

How can I display a $ sign with a value while using setw and setprecision in c++

I want to display the dollar sign next to its value in the second column, but if I convert the value into a string, the setprecision doesn't work and it displayed more decimals than I would like. Currently the formatting doesn't look good.
My current code:
string unit = "m";
double width = 30.123;
double length = 40.123;
double perimeter = 2 * width + 2 * length;
double area = width * length;
double rate = (area <= 3000) ? 0.03 : 0.02;
double cost = area * rate;
const int COLFMT = 20;
cout << fixed << setprecision(2);
cout << setw(COLFMT) << left << "Length:"
<< setw(COLFMT) << right << length << " " << unit << endl;
cout << setw(COLFMT) << left << "Width:"
<< setw(COLFMT) << right << width << " " << unit << endl;
cout << setw(COLFMT) << left << "Area:"
<< setw(COLFMT) << right << area << " square" << unit << endl;
cout << setw(COLFMT) << left << "Perimeter:"
<< setw(COLFMT) << right << perimeter << " " << unit << endl;
cout << setw(COLFMT) << left << "Rate:"
<< setw(COLFMT) << right << rate << "/sqaure" << unit << endl;
cout << setw(COLFMT) << left << "Cost:"
<< setw(COLFMT) << right << "$" << cost << endl;
Produces this poorly formatted output:
Length: 40.12 m
Width: 30.12 m
Area: 1208.63 square m
Perimeter: 140.49 m
Rate: 0.03/square m
Cost: $36.26
"Currently the formatting doesn't look good."
That's because std::right pertains to what follows it, in your case "$". So the dollar sign is right-aligned and not the value that follows on afterwards.
What you want is the fully formatted monetary value "$36.26" to be right aligned. So build that up as a string first with stringstream.
stringstream ss;
ss << fixed << setprecision(2) << "$" << cost;
cout << left << "Cost:" << setw(COLFMT) << right << ss.str() << endl;

C++ How To Show Percentage Output Of Dice Simulator Results

newbie here to C++. I am having trouble displaying the correct format + results in percentage form for this dice simulator our professor has asked us to make. I'll copy/paste her instructions here and would appreciate help with how to correct my mistake(s) in regard to the formatting of the percentage output in my program. Thank you!
INSTRUCTIONS:
This program should simulate the roll of a single die (dice) (1-6) using the C++ random number functions. First ask the user how many times they would like to have the die (dice) rolled.
Next, have the program simulate the number of rolls of the die (dice) the user requested and keep track of which number the die (dice) landed on for each roll. At the end of the program print out a report showing how many times the die (dice) roll landed on each number and what percentage of the total times the die (dice) roll landed on each number.
Do NOT use functions or arrays on this - use what I showed you during lecture, you should always listen during lecture to get the right techniques, if you forgot what I said during lecture look at the slides.
Input Validation: Do not allow the user to enter a number less than 1 as the number of times they would like to roll the dice.
How output should be (on left) vs what mine outputs (on right):
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
srand((unsigned int)time(NULL));
int timesRolled;
int rolled;
float num1 = 0;
float num2 = 0;
float num3 = 0;
float num4 = 0;
float num5 = 0;
float num6 = 0;
cout << "How many times would you like to roll the dice?" << endl;
cin >> timesRolled;
for (int i = 0; i < timesRolled; i++)
{
rolled = rand() % 6 + 1;
if (rolled == 1)
{
num1++;
}
else if (rolled == 2)
{
num2++;
}
else if (rolled == 3)
{
num3++;
}
else if (rolled == 4)
{
num4++;
}
else if (rolled == 5)
{
num5++;
}
else if (rolled == 6)
{
num6++;
}
}
while (timesRolled < 1)
{
cout << "This is an invalid number. " << endl
<< "The number of rolls should be equal to or greater than 1." << endl
<< "Please enter again." << endl;
cin >> timesRolled;
}
cout << "\nDICE ROLL STATISTICS" << endl << endl
<< "# Rolled # Times % Times" << endl
<< "-------- -------- --------" << endl
<< setw(7) << "1" << setw(17) << fixed << setprecision(0) << num1 << setw(17) << fixed << setprecision(2) << (num1 / timesRolled) * 100 << "%" << endl
<< setw(7) << "2" << setw(17) << fixed << setprecision(0) << num2 << setw(17) << fixed << setprecision(2) << (num2 / timesRolled) * 100 << "%" << endl
<< setw(7) << "3" << setw(17) << fixed << setprecision(0) << num3 << setw(17) << fixed << setprecision(2) << (num3 / timesRolled) * 100 << "%" << endl
<< setw(7) << "4" << setw(17) << fixed << setprecision(0) << num4 << setw(17) << fixed << setprecision(2) << (num4 / timesRolled) * 100 << "%" << endl
<< setw(7) << "5" << setw(17) << fixed << setprecision(0) << num5 << setw(17) << fixed << setprecision(2) << (num5 / timesRolled) * 100 << "%" << endl
<< setw(7) << "6" << setw(17) << fixed << setprecision(0) << num6 << setw(17) << fixed << setprecision(2) << (num6 / timesRolled) * 100 << "%" << endl;
system("PAUSE");
return 0;
}
You can see where I tried to use setprecision (at the end of my program) to manipulate the output of decimals in my final percentage number, but it doesn't seem to be working and this is where I need help please.
Your problem is an integer division e.g.:
(num1 / timesRolled) * 100 = 10 / 50 * 100 = 0 * 100 = 0;
Use floating point values instead or cast before division:
float num1 = 0;
or
(static_cast<float>(num1) / timesRolled) * 100

C++ setup columns using cout

So i'm just starting to learn c++ and i'm curious if its a way to formate your output with cout so it will look nicely and structured in columns
for example.
string fname = "testname";
string lname = "123";
double height = 1.6;
string fname2 = "short";
string lname2 = "123";
double height2 = 1.8;
cout << "Name" << setw(30) << "Height[m]" << endl;
cout << fname + " " + lname << right << setw(20) << setprecision(2) << fixed << height << endl;
cout << fname2 + " " + lname2 << right << setw(20) << setprecision(2) << fixed << height2 << endl
The output looks like this:
Name Height[m]
testname 123 1.60
short 123 1.80
I want it to look like this:
Name Height[m]
testname 123 1.60
short 123 1.80
The problem i'm trying to solve is that i want to place height at a specific position from name but depending what length of name i take the value of height either gets far away to the right or will be very close to the left. Is there a way to fix this?
First of all, with an output stream like std::cout, you cannot travel back in time and modify output which was already performed. That makes sense -- just imagine std::cout wrote into a file because you launched your program with program.exe > test.txt, and test.txt was on a USB drive which has been disconnected in the meanwhile...
So you have to get it right immediately.
Basically, there are two ways to do so.
You can assume that no entry in the first column will ever be wider than a certain number of characters, which is what you have attempted. The problem is that your setw is at the wrong position and that right should be left. A stream manipulator must be placed before the elements which should be affected. And since you want left-aligned columns, you need left:
cout << left << setw(20) << "Name" << "Height[m]" << endl;
cout << left << setw(20) << fname + " " + lname << setprecision(2) << fixed << height << endl;
cout << left << setw(20) << fname2 + " " + lname2 << setprecision(2) << fixed << height2 << endl;
But this solution is not very general. What if you'll have a name with 21 characters? Or with 30 characters? Or 100 characters? What you really want is a solution in which the column is automatically set only as wide as necessary.
The only way to do this is to collect all entries before printing them, finding the longest one, setting the column width accordingly and only then print everything.
Here is one possible implementation of this idea:
std::vector<std::string> const first_column_entries
{
"Name",
fname + " " + lname,
fname2 + " " + lname2
};
auto const width_of_longest_entry = std::max_element(std::begin(first_column_entries), std::end(first_column_entries),
[](std::string const& lhs, std::string const& rhs)
{
return lhs.size() < rhs.size();
}
)->size();
// some margin:
auto const column_width = width_of_longest_entry + 3;
std::cout << std::left << std::setw(column_width) << "Name" << "Height[m]" << "\n";
std::cout << std::left << std::setw(column_width) << fname + " " + lname << std::setprecision(2) << std::fixed << height << "\n";
std::cout << std::left << std::setw(column_width) << fname2 + " " + lname2 << std::setprecision(2) << std::fixed << height2 << "\n";
The next step of evolution would be generalising the std::vector into a self-written class called Table and iterating that Table's rows in a loop in order to print the entries.
string fname = "testname";
string lname = "123";
double height = 1.6;
string fname2 = "short";
string lname2 = "123";
double height2 = 1.8;
cout << left << setw(30) << "Name" << left << "Height[m]" << endl;
cout << left << setw(30) << fname + " " + lname << right << setw(6) << setprecision(2) << fixed << height << endl;
cout << left << setw(30) << fname2 + " " + lname2 << right << setw(6) << setprecision(2) << fixed << height2 << endl;

Display data in two columns c++

I am trying to display the same data but in two columns, so after school week 19, the data should be displayed in the columns to the right of the table until the total school weeks is reached i.e. 36. Below is the code:
#include "stdafx.h"
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
int const schoolWeeks = 37;
string week[] = { "A", "B", "C", "D" };
int num = 0;
int main()
{
cout << left << setw(9) << setfill(' ') << "Week " << left << setw(9) << setfill(' ')<< "Menu" << left << setw(9) << setfill(' ') << "Week " << "Menu" << endl;
for (int i = 1; i < 20; i++)
{
cout << left << setw(9) << setfill(' ')<< i << week[num] << endl;
num = num + 1;
if (num == 4)
{
num = 0;
}
}
for (int i = 20; i < schoolWeeks; i++)
{
cout << left << setw(9) << setfill(' ') << i << week[num] << endl;
num = num + 1;
if (num == 4)
{
num = 0;
}
}
}
Standard output with std::cout is based on the idea of a stream of data. Remember, it's called "iostream" for a reason. This means once you have written something to std::cout, you simply cannot "go back" a few lines and add something.
Consider piping in a Linux shell or on the Windows command line. It's possible to redirect the output of your program to be the input of another program, which could then do any imaginable thing with it, e.g. sending it over the internet:
myprogram.exe > otherprogram.exe
How could you possibly add something to an already written line in such a scenario?
Considering all of this, it becomes clear that the only viable solution is to know in advance the contents of every line. You cannot wait until line 19 before thinking about the second column, you must do it right away. In other words, first print week 1 and week 19, then week 2 and week 20, then week 3 and week 21, and so on. See the pattern? It's always "week X in column one, week X+18 in column two". And that's pretty much the solution.
Here's a quickly written loop adhering to the style of your existing code:
for (int i = 1; i < 19; i++)
{
cout << left << setw(9) << setfill(' ')<< i << week[num]
<< left << setw(9) << setfill(' ') << " " << (i + 18) << " "
<< left << setw(9) << setfill(' ') << " " << week[num]
<< endl;
num = num + 1;
if (num == 4)
{
num = 0;
}
}
The manipulators like std::setw or std::setfill could probably use some improvement, but the point is that:
The loop only counts from 1 to 18.
The body performs the output for i and for i + 18.

setw not working as expected

I'm trying to print time in hh:mm format but when the time is like 01:01 it prints as 1:1. Here's my code:
void output(int hour, int min, char ampm){
cout << setw(2) << setfill('0') << "The time is: " << hour << ":" << min << " ";
if(ampm == 'P'){
cout << "PM";
}
else if (ampm == 'A'){
cout << "AM";
}
}
As I understand it, this should work. I include iomanip. Can you see anything wrong with it?
The width is a special formatting setting: While all other formatting flags are stick, the width() will be reset by each output operator (well, you can have user-defined output operators which don't reset the width() but doing so would not follow the normal style). That is, you need to set the width immediately prior to the output that should be affected:
std::cout << std::setfill('0')
<< std::setw(2) << hour << ':'
<< std::setw(2) << min << ' ';
Following is correct way:
cout<<""The time is: ";
cout << setfill('0') <<setw(2) << hour << ":" <<setw(2) << min << " ";
Ref :-this