I'm not great at using the iomanip library and have tried looking around for similar problems, but haven't been able to implement a good solution. I'm trying to display words that are used most frequently and least frequently. My code is (abridged version showing what I'm having problems with):
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
int main() {
string word1 = "helloooo";
string word2 = "hey";
cout << "MOST FREQUENT: ";
cout << setw(7) << left << word1;
cout << setw(5) << right << "(" << 5 << ")" << endl;
cout << "LEAST FREQUENT: ";
cout << setw(9) << left << word2;
cout << setw(5) << right << "(" << 3 << ")" << endl;
}
This is only a simpler version of the code I'm working on. In reality, the words will be pulled from a vector and the numbers will be different. The words should be center aligned and the right side should show the number in a column. I want it to look like:
MOST FREQUENT: hellooooo (5)
LEAST FREQUENT: hey (3)
But instead I get:
MOST FREQUENT: helloooo (5)
LEAST FREQUENT: hey (3)
I'm just not good using iomanip and any help would be appreciated!
Related
I am trying to parse through a text file and have it output the contents onto the console with formatting by using setw(). My problem is that only the first row is formatted correctly, with the rest defaulting back to the left.
while (test)
{
cout << setw(20) << right;
string menu;
price = 0;
getline(test, menu, ',');
test >> price;
cout << setw(20) << right << menu;;
if (price)
cout << right << setw(10) << price;
}
My goal is to get the output to align to the longest word (which is 20 spaces in length) on the right, but my output is ending up like this:
WordThatAlignsRight
notAligning
my longest sentence goal align
notAligning
I am wanting each sentence to right align 20 spaces throughout the loop. Any help is appreciated, thanks!
std::setw only works on the next element, after that there is no effect. For further information pls follow this link..
The code on the linked site will show you very clearly how std::setw works.
#include <sstream>
#include <iostream>
#include <iomanip>
int main()
{
std::cout << "no setw:" << 42 << '\n'
<< "setw(6):" << std::setw(6) << 42 << '\n'
<< "setw(6), several elements: " << 89 << std::setw(6) << 12 << 34 << '\n';
std::istringstream is("hello, world");
char arr[10];
is >> std::setw(6) >> arr;
std::cout << "Input from \"" << is.str() << "\" with setw(6) gave \""
<< arr << "\"\n";
}
Output:
no setw:42
setw(6): 42
setw(6), several elements: 89 1234
Input from "hello, world" with setw(6) gave "hello"
I am trying to format a 'cout' where it has to display something like this:
Result $ 34.45
The amount ($ 34.45) has to be on right index with certain amount of padding or end at certain column position. I tried using
cout << "Result" << setw(15) << right << "$ " << 34.45" << endl;
However, it's setting the width for the "$ " string, not for the string plus amount.
Any advice on dealing with such formatting?
You need to combine "$ " and value 34.45 into separate string. Try like this:
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
using namespace std;
int main()
{
stringstream ss;
ss << "$ " << 34.45;
cout << "Result" << setw(15) << right << ss.str() << endl;
}
You try to apply a format modifier to two arguments of different types (string literal and a double), which can't work out. To set a width for both the "$ " and the number, you need to convert both to a string first. One way would be
std::ostringstream os;
os << "$ " << 34.45;
const std::string moneyStr = os.str();
std::cout << "Result" << std::setw(15) << std::right << moneyStr << "\n";
This is admittedly verbose, so you may put the first part in a helper function. Also, std::ostringstream formatting might not be the best choice, you can also have a look at std::snprintf (overload 4).
An alternative could be to use std::put_money.
#include <iostream>
#include <locale>
#include <iomanip>
void disp_money(double money) {
std::cout << std::setw(15) << std::showbase << std::put_money(money*100.)<< "\n";
}
int main() {
std::cout.imbue(std::locale("en_US.UTF-8"));
disp_money(12345678.9);
disp_money(12.23);
disp_money(120.23);
}
Output
$12,345,678.90
$12.23
$120.23
I'm asking this after googling for 2 hours now. As the title says I think I'm misunderstanding how to use the two things above. I'm attempting to create two distinct columns that show output and are in line with one another. However it seems no matter what I do they won't line up.
My code is as follows
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
int main()
{
const double THEATHERCUT = .80;
const double DISTRIBUTORCUT = .20;
const int CHILDCOST = 6;
const int ADULTCOST = 10;
string movieName;
int childTickets, adultTickets, childGrossRevenue, adultGrossRevenue, totalGrossRevenue, distributorRevenue, totalNetRevenue;
//User Input
cout << "What movie was viewed?" << endl;
getline(cin, movieName);
cout << "How many adult tickets were sold?" << endl;
cin >> adultTickets;
cout << "How many child tickets were sold?" << endl;
cin >> childTickets;
// Maths
childGrossRevenue = (CHILDCOST * childTickets);
adultGrossRevenue = (ADULTCOST * adultTickets);
totalGrossRevenue = (childGrossRevenue + adultGrossRevenue);
distributorRevenue = (totalGrossRevenue * .20);
totalNetRevenue = (totalGrossRevenue * .80);
cout << left << "Movie Name:" << setw(20) << right << movieName << endl;
cout << left << "Adult Tickets Sold:" << setw(20) << right << adultTickets << endl;
cout << left << "Child Tickets Sold:" << setw(20) << right << childTickets << endl;
cout << left << "Gross Box Office Revenue:" << setw(20) << right << totalGrossRevenue << endl;
cout << left << "Amount Paid to Distributor:" << setw(20) << right << distributorRevenue << endl;
cout << left << "Net Box Office Revenue:" << setw(20) << right << totalNetRevenue << endl;
system("pause");
return 0;
}
As far as my understanding goes the first cout line should do the following:
Align "Movie Name:" to the left, setw(20) set a 20 space padding between the "Movie Name:" and movieName. right then justifies movieName to the right. Is this correct? Just for clarification this is how I'd like it to look.
(I'm also well aware using system("pause") is sacrilegious before anyone mentions it.)
setw(20) set a 20 space padding between the "Movie Name:" and movieName. right then justifies movieName to the right. Is this correct?
No.
setw(20) sets the next "field" to be 20-characters wide, triggering the insertion of additional whitespace if the field is shorter (resulting in an "alignment" effect in the output of subsequent fields).
This must come before the field is inserted otherwise you have a temporal paradox.
The field you're trying to pad is the "Movie Name:" part, so move your setws one to the left.
left and right align within a field, which doesn't seem to be what you are after, so drop right.
(live demo*)
* I have killed two unused variables, fixed indentation, remove sacrilegiousness (I literally had to or this demo wouldn't work — evil!), and increased your spacing (since 20 isn't actually enough to fit column 1 in all your rows). Otherwise the changes are only as recommended above.
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.
I'd like to display numbers using a padding (if necessary) and a fixed number of digits. For instance, given the following numbers:
48.3
0.3485
5.2
Display them like this:
48.30
00.35
05.20
I'm trying combinations of std::fixed, std::fill, std::setw, and std::setprecision, but I can't seem to get what I'm looking for. Would love some guidance!
NOTE: The 0-padding isn't really critical, but I'd still like the numbers to be aligned such that the decimal point is in the same column.
It's pretty straightforward
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
cout << fixed << setprecision(2) << setfill('0');
cout << setw(5) << 48.3 << endl;
cout << setw(5) << 0.3485 << endl;
cout << setw(5) << 5.2 << endl;
}
Writing code like this makes me yearn for printf however.