C++ Conversion to Monetary Values - c++

About the Program
I have a program that displays a menu. The menu contains both an array of items (strings), and prices (double type values). The program serves no further purpose but to display a menu.
The Problem
Of course, by default the double type values are displayed with decimals. This is useful in this case because we are listing the prices of items; however, usually prices initially begin with a dollar sign ($). To my knowledge, the iomanip header contains the "put_money" & "put_money" functions, but these do not do what I need them to do. What I need is for each price within to menu to be displayed with a dollar sign alongside the actual value. For example:
My desired output is this:
Please select an item to purchase:
______________________________________________________
Item: Prices: Item: Prices: Item: Prices:
______________________________________________________
Water $100 Milk $200 Juice $300
Wine $400 Bread $500 Apple $600
Tuna $700 Steak $800 Bandage $900
Med-Kit $1000 Splint $1100 Thread $1200
My current program produces this:
Please select an item to purchase:
______________________________________________________
Item: Prices: Item: Prices: Item: Prices:
______________________________________________________
Water 100 Milk 200 Juice 300
Wine 400 Bread 500 Apple 600
Tuna 700 Steak 800 Bandage 900
Med-Kit 1000 Splint 1100 Thread 1200
Is there a more efficient way to add the dollar sign to all my values without having to manually add each individual dollar sign? I just felt manually adding them could be tedious in a large project (certainly not like this, but possibly similar).
My Code
#include <iostream>
#include <iomanip>
#include <string>
int main(void) {
unsigned short int width = 10;
unsigned short int prec = 6;
float prices[12] = {100.00, 200.00, 300.00, 400.00, 500.00, 600.00, 700.00, 800.00, 900.00, 1000.00, 1100.00, 1200.00};
std::string items[12] = {"Water", "Milk", "Juice", "Wine", "Bread", "Apple", "Tuna", "Steak", "Bandage", "Med-Kit", "Splint","Thread"};
std::cout << "\nPlease select an item to purchase:\n\n";
std::cout << "_________________________________________________________________\n\n";
std::cout << std::setw(width) << "Item:" << std::setw(width) << "Prices:" <<std::setw(width) << "Item:" <<std::setw(width) << "Prices;" <<std::setw(width) << "Item:" <<std::setw(width) << "Prices:" << "\n";
std::cout << "_________________________________________________________________\n\n";
std::cout << std::setw(width) <<items[0] <<std::setw(width) << prices[0] <<std::setw(width) << items[1] <<std::setw(width) << prices[1] <<std::setw(width) << items[2] <<std::setw(width) << prices[2] << "\n";
std::cout << std::setw(width) <<items[3] <<std::setw(width) << prices[3] <<std::setw(width) << items[4] <<std::setw(width) << prices[4] <<std::setw(width) << items[5] <<std::setw(width) << prices[5] << "\n";
std::cout << std::setw(width) <<items[6] <<std::setw(width) << prices[6] <<std::setw(width) << items[7] <<std::setw(width) << prices[7] <<std::setw(width) << items[8] <<std::setw(width) << prices[8] << "\n";
std::cout << std::setw(width) <<items[9] <<std::setw(width) << prices[9] <<std::setw(width) << items[10] <<std::setw(width) << prices[10] <<std::setw(width) << items[11] <<std::setw(width) << prices[11] << "\n";
std::cin.get();
std::cin.get();
return 0;
}
Please excuse the excessive length of the code. Thanks to everyone in advance for helping.

Why don't you create a class to store the items?
For example, you can have:
class Item
{
private:
double price;
string item;
public:
void display()
{
cout << "$" << price;
}
};
So you call the display function to display the price in monetary value.

Actually std::put_money can and will do exactly what you're asking if you use it correctly.
There are two parts to that. First of all, you have to select a locale. The default "C" locale simply doesn't define a currency symbol to use. Typically you'll want to use the nameless locale, something like this:
std::cout.imbue(std::locale(""));
This chooses (and uses) the locale for which the user has configured their environment, so (for example) a typical US user will get some US English locale with a dollar sign as the currency symbol, but a typical German user will get a German locale with a euro sign as the currency symbol1. This will also affect the formatting of the numbers. The example output below shows it using a comma as a thousands separator and a period (full-stop) as a decimal separator. Users in many European countries (for one example) should expect those two to be reversed.
Then you need to set the showbase flag for the stream. For other numbers, this tells the stream to show the base of the number as converted, so (for example) if you print out something in hexadecimal, it'll be preceded by a 0x (or 0X). When you write money, that gets re-purposed to saying whether to show the currency symbol or not.
You normally want to combine that with the advice you've already received about creating a class (or struct) to store the data about an item. Rather than a function named display, I'd create an overload of operator<< to display an item though.
Note that money values are stored as long doubles. In a typical case, it will be stored as an integral number of the smallest denomination of currency in normal use (e.g., in the US, an integral number of pennies). Therefore, initialization to 100.0 would actually mean a value of $1.002.
With that (and leaving out the code for your header), creating and displaying the table might look something like this:
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
unsigned short int width=10;
unsigned short int prec=6;
class item {
std::string name;
long double price;
public:
item(std::string const &name, double price): name(name), price(price) {}
friend std::ostream &operator<<(std::ostream &os, item const &i) {
return os<<std::setw(width) << i.name
<<std::setw(width) << std::showbase << std::put_money(i.price);
}
};
int main(void) {
std::vector<item> items {
{"water", 10000},
{"Milk", 20000},
{"Juice", 30000},
{"Wine", 40000},
{"Bread", 60000},
{"Apple", 70000},
{"Tuna", 80000},
{"Steak", 90000},
{"Bandage", 100000},
{"Med-Kit", 110000},
{"Splint", 120000},
{"Thread", 130000}
};
std::cout.imbue(std::locale(""));
unsigned count=0;
for (auto &&item:items) {
std::cout<<item;
if (++count==3) {
std::cout<<"\n";
count=0;
}
}
}
Result:
water $100.00 Milk $200.00 Juice $300.00
Wine $400.00 Bread $600.00 Apple $700.00
Tuna $800.00 Steak $900.00 Bandage $1,000.00
Med-Kit $1,100.00 Splint $1,200.00 Thread $1,300.00
If you decide to do the formatting on your own, be aware that it won't be quite as simple as just inserting a $ before the item to be written. The problem is that you pretty much need to explicitly set a width and precision when you write out the value. When you do that, you'll quickly find that the $ gets inserted before the padding for the number, so (for example) your first entry will end up looking something like this:
water$ 100.00
...instead of putting the currency symbol next to the number where you almost certainly want it. It is possible to prevent that with enough extra work:
std::ostringstream temp;
temp << '$' << std::setprecision(your_precision) << value;
std::cout << std::setw(your_width) << temp.str();
Although it may be open to argument that usingstd::put_money is a little more work than you'd like, by the time you get the formatting even reasonably close to correct on your own, it's quite a bit more work still (and adding even minimal support for internationalization is quite a bit more work again).
Do note, however, that while the symbol is automatically chosen based on the user's locale, no attempt is made to convert the value, so if I enter 1 dollar, and that value is displayed in a German locale, it'll show up as 1 Euro (and vice versa).
Technically, I don't believe the standard actually requires this, but it's how all the compilers I've seen actually do things. The standard does require that get_money and put_money are symmetrical, so if a user enters $100.00 and you read it with get_money, store whatever that produces, and then write it back out with put_money, you should get $100.00 as the result.

Related

Is there an easy way to print an int without removing leading zeros? [duplicate]

How can I format my output in C++? In other words, what is the C++ equivalent to the use of printf like this:
printf("%05d", zipCode);
I know I could just use printf in C++, but I would prefer the output operator <<.
Would you just use the following?
std::cout << "ZIP code: " << sprintf("%05d", zipCode) << std::endl;
This will do the trick, at least for non-negative numbers(a) such as the ZIP codes(b) mentioned in your question.
#include <iostream>
#include <iomanip>
using namespace std;
cout << setw(5) << setfill('0') << zipCode << endl;
// or use this if you don't like 'using namespace std;'
std::cout << std::setw(5) << std::setfill('0') << zipCode << std::endl;
The most common IO manipulators that control padding are:
std::setw(width) sets the width of the field.
std::setfill(fillchar) sets the fill character.
std::setiosflags(align) sets the alignment, where align is ios::left or ios::right.
And just on your preference for using <<, I'd strongly suggest you look into the fmt library (see https://github.com/fmtlib/fmt). This has been a great addition to our toolkit for formatting stuff and is much nicer than massively length stream pipelines, allowing you to do things like:
cout << fmt::format("{:05d}", zipCode);
And it's currently being targeted by LEWG toward C++20 as well, meaning it will hopefully be a base part of the language at that point (or almost certainly later if it doesn't quite sneak in).
(a) If you do need to handle negative numbers, you can use std::internal as follows:
cout << internal << setw(5) << setfill('0') << zipCode << endl;
This places the fill character between the sign and the magnitude.
(b) This ("all ZIP codes are non-negative") is an assumption on my part but a reasonably safe one, I'd warrant :-)
Use the setw and setfill calls:
std::cout << std::setw(5) << std::setfill('0') << zipCode << std::endl;
In C++20 you'll be able to do:
std::cout << std::format("{:05}", zipCode);
In the meantime you can use the {fmt} library, std::format is based on.
Disclaimer: I'm the author of {fmt} and C++20 std::format.
cout << setw(4) << setfill('0') << n << endl;
from:
http://www.fredosaurus.com/notes-cpp/io/omanipulators.html
or,
char t[32];
sprintf_s(t, "%05d", 1);
will output 00001 as the OP already wanted to do
Simple answer but it works!
ostream &operator<<(ostream &os, const Clock &c){
// format the output - if single digit, then needs to be padded with a 0
int hours = c.getHour();
// if hour is 1 digit, then pad with a 0, otherwise just print the hour
(hours < 10) ? os << '0' << hours : os << hours;
return os; // return the stream
}
I'm using a ternary operator but it can be translated into an if/else statement as follows
if(c.hour < 10){
os << '0' << hours;
}
else{
os << hours;
}

c++ align vertically text and variables [duplicate]

Is there a way to align text when printing using std::cout? I'm using tabs, but when the words are too big they won't be aligned anymore.
Sales Report for September 15, 2010
Artist Title Price Genre Disc Sale Tax Cash
Merle Blue 12.99 Country 4% 12.47 1.01 13.48
Richard Music 8.49 Classical 8% 7.81 0.66 8.47
Paula Shut 8.49 Classical 8% 7.81 0.72 8.49
The ISO C++ standard way to do it is to #include <iomanip> and use io manipulators like std::setw. However, that said, those io manipulators are a real pain to use even for text, and are just about unusable for formatting numbers (I assume you want your dollar amounts to line up on the decimal, have the correct number of significant digits, etc.). Even for just plain text labels, the code will look something like this for the first part of your first line:
// using standard iomanip facilities
cout << setw(20) << "Artist"
<< setw(20) << "Title"
<< setw(8) << "Price";
// ... not going to try to write the numeric formatting...
If you are able to use the Boost libraries, run (don't walk) and use the Boost.Format library instead. It is fully compatible with the standard iostreams, and it gives you all the goodness for easy formatting with printf/Posix formatting string, but without losing any of the power and convenience of iostreams themselves. For example, the first parts of your first two lines would look something like:
// using Boost.Format
cout << format("%-20s %-20s %-8s\n") % "Artist" % "Title" % "Price";
cout << format("%-20s %-20s %8.2f\n") % "Merle" % "Blue" % 12.99;
Another way to make column aligned is as follows:
using namespace std;
cout.width(20); cout << left << "Artist";
cout.width(20); cout << left << "Title";
cout.width(10); cout << left << "Price";
...
cout.width(20); cout << left << artist;
cout.width(20); cout << left << title;
cout.width(10); cout << left << price;
We should estimate maximum length of values for each column. In this case, values of "Artist" column should not exceed 20 characters and so on.
IO manipulators are what you need. setw, in particular. Here's an example from the reference page:
// setw example
#include <iostream>
#include <iomanip>
using namespace std;
int main () {
cout << setw (10);
cout << 77 << endl;
return 0;
}
Justifying the field to the left and right is done with the left and right manipulators.
Also take a look at setfill. Here's a more complete tutorial on formatting C++ output with io manipulators.
See also: Which C I/O library should be used in C++ code?
struct Item
{
std::string artist;
std::string c;
integer price; // in cents (as floating point is not acurate)
std::string Genre;
integer disc;
integer sale;
integer tax;
};
std::cout << "Sales Report for September 15, 2010\n"
<< "Artist Title Price Genre Disc Sale Tax Cash\n";
FOREACH(Item loop,data)
{
fprintf(stdout,"%8s%8s%8.2f%7s%1s%8.2f%8.2f\n",
, loop.artist
, loop.title
, loop.price / 100.0
, loop.Genre
, loop.disc , "%"
, loop.sale / 100.0
, loop.tax / 100.0);
// or
std::cout << std::setw(8) << loop.artist
<< std::setw(8) << loop.title
<< std::setw(8) << fixed << setprecision(2) << loop.price / 100.0
<< std::setw(8) << loop.Genre
<< std::setw(7) << loop.disc << std::setw(1) << "%"
<< std::setw(8) << fixed << setprecision(2) << loop.sale / 100.0
<< std::setw(8) << fixed << setprecision(2) << loop.tax / 100.0
<< "\n";
// or
std::cout << boost::format("%8s%8s%8.2f%7s%1s%8.2f%8.2f\n")
% loop.artist
% loop.title
% loop.price / 100.0
% loop.Genre
% loop.disc % "%"
% loop.sale / 100.0
% loop.tax / 100.0;
}
At the time you emit the very first line,
Artist Title Price Genre Disc Sale Tax Cash
to achieve "alignment", you have to know "in advance" how wide each column will need to be (otherwise, alignment is impossible). Once you do know the needed width for each column (there are several possible ways to achieve that depending on where your data's coming from), then the setw function mentioned in the other answer will help, or (more brutally;-) you could emit carefully computed number of extra spaces (clunky, to be sure), etc. I don't recommend tabs anyway as you have no real control on how the final output device will render those, in general.
Back to the core issue, if you have each column's value in a vector<T> of some sort, for example, you can do a first formatting pass to determine the maximum width of the column, for example (be sure to take into account the width of the header for the column, too, of course).
If your rows are coming "one by one", and alignment is crucial, you'll have to cache or buffer the rows as they come in (in memory if they fit, otherwise on a disk file that you'll later "rewind" and re-read from the start), taking care to keep updated the vector of "maximum widths of each column" as the rows do come. You can't output anything (not even the headers!), if keeping alignment is crucial, until you've seen the very last row (unless you somehow magically have previous knowledge of the columns' widths, of course;-).
C++20 std::format options <, ^ and >
According to https://en.cppreference.com/w/cpp/utility/format/formatter#Standard_format_specification the following should hold:
#include <format>
// left: "42 "
std::cout << std::format("{:<6}", 42);
// right: " 42"
std::cout << std::format("{:>6}", 42);
// center: " 42 "
std::cout << std::format("{:^6}", 42);
The existing fmt library implements it for before it gets official support: https://github.com/fmtlib/fmt Install on Ubuntu 22.04:
sudo apt install libfmt-dev
Modify source to replace:
<format> with <fmt/core.h>
std::format to fmt::format
main.cpp
#include <iostream>
#include <fmt/core.h>
int main() {
std::cout << "123456.\n";
// left
std::cout << fmt::format("{:<6}.\n", 42);
// right
std::cout << fmt::format("{:>6}.\n", 42);
// center
std::cout << fmt::format("{:^6}.\n", 42);
}
and compile and run with:
g++ -std=c++11 -o main.out main.cpp -lfmt
./main.out
Output:
123456.
42 .
42.
42 .
More information at: std::string formatting like sprintf
The easiest way, without the use of "complex" functions, is to format by hand:
an example:
std::cout << std::setprecision(10)
<< "integral of sin(x) from x = 0 to x = pi" << '\n'
<< "approximate: " << integrate(a, b, nbins) << '\n'
<< "exact: " << 2.0 << '\n';

Structured output

I recently started programming in c++ and I've bumped into a small problem. If I want my output to be structured (let's say that every line starts with a name and then a number) in a way that the names are written normally to the screen (every first letter of every name starts at the beginning of each new line) and I want the numbers that follow to be lined up in a column, how would I do this? I want the programs output to look like this:
Gary 0
LongName 0
VerylongName 0
I want my program to print something in the way above, but with different lengths of names (and the '0' in this case, lined up in a column).
Try the following: if you know the maximum length of all the names you intend to print (e.g. 20), then use the C++ i/o manipulators to set the width of the output (and left-justification). This will force the output to take up max characters.
Code snippet:
#include <iostream>
#include <iomanip>
...
// for each entry
std::cout << std::setw(20) << std::left << "Gary" << 10 << "\n";
...
std::cout << std::flush;
Here's some more information...
I'm shooting in the dark here since you haven't really included much information... HOWEVER one way you can do this is to make sure that you create the columns with padding around the name - and not worry about the numbers. Formatted output is one case where C has an advantage over C++ (IMHO). In C++ you can also do this with something like this:
cout << setw(15) << name << number << "\n";
Bonus points if you figure out ahead of time the maximum length of the name you have and add, say, 4 to it.
Not in the C++ standard library, but still worth mentioning: boost::format. It will let you write printf-like format strings while still being type-safe.
Example:
#include <boost/format.hpp>
#include <iostream>
#include <string>
struct PersonData
{
std::string name;
int age;
};
PersonData persons[] =
{
{"Gary", 1},
{"Whitney", 12},
{"Josephine ", 101}
};
int main(void)
{
for (auto person : persons)
{
std::cout << boost::format("%-20s %5i") % person.name % person.age << std::endl;
}
return 0;
}
Outputs:
Gary 1
Whitney 12
Josephine 101
struct X
{
const char *s;
int num;
} tab[] = {
{"Gary",1},
{"LongName",23},
{"VeryLongName",456}
};
int main(void)
{
for (int i = 0; i < sizeof(tab) / sizeof(struct X); i++ )
{
// C like - example width 20chars
//printf( "%-20s %5i\n", tab[i].s, tab[i].num );
// C++ like
std::cout << std::setw(20) << std::left << tab[i].s << std::setw(5) << std::right << tab[i].num << std::endl;
}
getchar();
return 0;
}

How do I turn off std::fixed and return to the default C++ setting

My code:
std::vector<double> thePoint(4);
thePoint[0] = 86;
thePoint[1] = -334.8836574;
thePoint[2] = 24.283;
thePoint[3] = 345.67675;
ofstream file1(tempFileName, ios::trunc);
file1 << std::setprecision(16) << thePoint[0] << " ";
file1 << std::fixed << std::setprecision(2) << thePoint[1] << " ";
file1 << std::setprecision(16) << thePoint[2] << " ";
file1 << std::setprecision(16) << thePoint[3];
I get:
86 -334.88 24.28300000000000 345.6767500000000
I want:
86 -334.88 24.283 345.67675
The odd formatting is needed for an interface with other picky code.
You should do this:
file1 << std::fixed << std::setprecision(2) << thePoint[1] << " ";
file1.unsetf(ios_base::fixed);
file1 << std::setprecision(16) << thePoint[2];
The floatfield format flag can take any of its two possible values (using the manipulators fixed and scientific), or none of them (using ios_base::unsetf).
You can do it by forcing the floatfield to an empty value:
file1.setf( std::ios_base::fmtflags(), std::floatfield );
In practice, it's rare to want to, however. The usual protocol is to
save the format flags, and restore them when you're through:
std::ios_base::fmtflags originalFlags = file1.flags();
// ...
file1.flags( originalFlags );
Of course, you'd normally use RAII to do this in a real program. You
should have a IOSave class in your toolbox which will save the flags,
the precision and the fill character in its constructor, and restore
them in the destructor.
It's also not very good practice to use std::setprection etc.
directly. A better solution would be to define your own manipulators,
with names like pression or volume, and use those. This is logical
markup, and means that you control the format for e.g. pression from one
central location, rather than having it spread throughout the program.
And if you write your own manipulators, it's relatively easy to have
them restore the original formatting parameters at the end of the full
expression. (The manipulator objects will be temporaries, destructed at
the end of the full expression.)

C++ alignment when printing cout <<

Is there a way to align text when printing using std::cout? I'm using tabs, but when the words are too big they won't be aligned anymore.
Sales Report for September 15, 2010
Artist Title Price Genre Disc Sale Tax Cash
Merle Blue 12.99 Country 4% 12.47 1.01 13.48
Richard Music 8.49 Classical 8% 7.81 0.66 8.47
Paula Shut 8.49 Classical 8% 7.81 0.72 8.49
The ISO C++ standard way to do it is to #include <iomanip> and use io manipulators like std::setw. However, that said, those io manipulators are a real pain to use even for text, and are just about unusable for formatting numbers (I assume you want your dollar amounts to line up on the decimal, have the correct number of significant digits, etc.). Even for just plain text labels, the code will look something like this for the first part of your first line:
// using standard iomanip facilities
cout << setw(20) << "Artist"
<< setw(20) << "Title"
<< setw(8) << "Price";
// ... not going to try to write the numeric formatting...
If you are able to use the Boost libraries, run (don't walk) and use the Boost.Format library instead. It is fully compatible with the standard iostreams, and it gives you all the goodness for easy formatting with printf/Posix formatting string, but without losing any of the power and convenience of iostreams themselves. For example, the first parts of your first two lines would look something like:
// using Boost.Format
cout << format("%-20s %-20s %-8s\n") % "Artist" % "Title" % "Price";
cout << format("%-20s %-20s %8.2f\n") % "Merle" % "Blue" % 12.99;
Another way to make column aligned is as follows:
using namespace std;
cout.width(20); cout << left << "Artist";
cout.width(20); cout << left << "Title";
cout.width(10); cout << left << "Price";
...
cout.width(20); cout << left << artist;
cout.width(20); cout << left << title;
cout.width(10); cout << left << price;
We should estimate maximum length of values for each column. In this case, values of "Artist" column should not exceed 20 characters and so on.
IO manipulators are what you need. setw, in particular. Here's an example from the reference page:
// setw example
#include <iostream>
#include <iomanip>
using namespace std;
int main () {
cout << setw (10);
cout << 77 << endl;
return 0;
}
Justifying the field to the left and right is done with the left and right manipulators.
Also take a look at setfill. Here's a more complete tutorial on formatting C++ output with io manipulators.
See also: Which C I/O library should be used in C++ code?
struct Item
{
std::string artist;
std::string c;
integer price; // in cents (as floating point is not acurate)
std::string Genre;
integer disc;
integer sale;
integer tax;
};
std::cout << "Sales Report for September 15, 2010\n"
<< "Artist Title Price Genre Disc Sale Tax Cash\n";
FOREACH(Item loop,data)
{
fprintf(stdout,"%8s%8s%8.2f%7s%1s%8.2f%8.2f\n",
, loop.artist
, loop.title
, loop.price / 100.0
, loop.Genre
, loop.disc , "%"
, loop.sale / 100.0
, loop.tax / 100.0);
// or
std::cout << std::setw(8) << loop.artist
<< std::setw(8) << loop.title
<< std::setw(8) << fixed << setprecision(2) << loop.price / 100.0
<< std::setw(8) << loop.Genre
<< std::setw(7) << loop.disc << std::setw(1) << "%"
<< std::setw(8) << fixed << setprecision(2) << loop.sale / 100.0
<< std::setw(8) << fixed << setprecision(2) << loop.tax / 100.0
<< "\n";
// or
std::cout << boost::format("%8s%8s%8.2f%7s%1s%8.2f%8.2f\n")
% loop.artist
% loop.title
% loop.price / 100.0
% loop.Genre
% loop.disc % "%"
% loop.sale / 100.0
% loop.tax / 100.0;
}
At the time you emit the very first line,
Artist Title Price Genre Disc Sale Tax Cash
to achieve "alignment", you have to know "in advance" how wide each column will need to be (otherwise, alignment is impossible). Once you do know the needed width for each column (there are several possible ways to achieve that depending on where your data's coming from), then the setw function mentioned in the other answer will help, or (more brutally;-) you could emit carefully computed number of extra spaces (clunky, to be sure), etc. I don't recommend tabs anyway as you have no real control on how the final output device will render those, in general.
Back to the core issue, if you have each column's value in a vector<T> of some sort, for example, you can do a first formatting pass to determine the maximum width of the column, for example (be sure to take into account the width of the header for the column, too, of course).
If your rows are coming "one by one", and alignment is crucial, you'll have to cache or buffer the rows as they come in (in memory if they fit, otherwise on a disk file that you'll later "rewind" and re-read from the start), taking care to keep updated the vector of "maximum widths of each column" as the rows do come. You can't output anything (not even the headers!), if keeping alignment is crucial, until you've seen the very last row (unless you somehow magically have previous knowledge of the columns' widths, of course;-).
C++20 std::format options <, ^ and >
According to https://en.cppreference.com/w/cpp/utility/format/formatter#Standard_format_specification the following should hold:
#include <format>
// left: "42 "
std::cout << std::format("{:<6}", 42);
// right: " 42"
std::cout << std::format("{:>6}", 42);
// center: " 42 "
std::cout << std::format("{:^6}", 42);
The existing fmt library implements it for before it gets official support: https://github.com/fmtlib/fmt Install on Ubuntu 22.04:
sudo apt install libfmt-dev
Modify source to replace:
<format> with <fmt/core.h>
std::format to fmt::format
main.cpp
#include <iostream>
#include <fmt/core.h>
int main() {
std::cout << "123456.\n";
// left
std::cout << fmt::format("{:<6}.\n", 42);
// right
std::cout << fmt::format("{:>6}.\n", 42);
// center
std::cout << fmt::format("{:^6}.\n", 42);
}
and compile and run with:
g++ -std=c++11 -o main.out main.cpp -lfmt
./main.out
Output:
123456.
42 .
42.
42 .
More information at: std::string formatting like sprintf
The easiest way, without the use of "complex" functions, is to format by hand:
an example:
std::cout << std::setprecision(10)
<< "integral of sin(x) from x = 0 to x = pi" << '\n'
<< "approximate: " << integrate(a, b, nbins) << '\n'
<< "exact: " << 2.0 << '\n';