c++ align vertically text and variables [duplicate] - c++

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';

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++ Conversion to Monetary Values

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.

How can I format user input into a neat table for output in C++

I am having problems with getting this table to line up correctly, this is a cout statement from my table. My problem is how can I format different things in one line without it messing up the next entry in the line. For example, when I use setprecision(2) for my goldweight, the goldvalue gets messed up and gives me a weird number like 5656e+02
cout << " Value Analysis" <<endl;
cout << "Gold: " << setw(6) << "" <<goldweight<< " Oz # "<<costgold<<"
("<<setw(1)<< ""<<carats<<" Carats) $"<<goldvalue<<endl;
Yes, setw(), setprecision(), etc will mess up stuff.
What you can do is to use temporary std::ostringstream.
#include <sstream>
...
std::ostringstream oss_goldweight ;
std::ostringstream oss_goldvalue ;
std::ostringstream oss_goldcarats ;
oss_goldweight << setw(6) << goldweight ;
oss_goldvalue << setprecision(2) << goldvalue ;
oss_goldcarats << setw(1) << carats ;
and then use oss_goldxyz variables instead of raw values.
you need to reset it for the next input, like if you already set a precision, then you set it back (unset)
std::cout.unsetf ( std::ios::floatfield );

format, iomanip, c++

I'm trying to learn to use namespaces declarations more definitive than not just say "using namespace std". I'm trying to format my data to 2 decimal places, and set the format to be fixed and not scientific. This is my main file:
#include <iostream>
#include <iomanip>
#include "SavingsAccount.h"
using std::cout;
using std::setprecision;
using std::ios_base;
int main()
{
SavingsAccount *saver1 = new SavingsAccount(2000.00);
SavingsAccount *saver2 = new SavingsAccount(3000.00);
SavingsAccount::modifyInterestRate(.03);
saver1->calculateMonthlyInterest();
saver2->calculateMonthlyInterest();
cout << ios_base::fixed << "saver1\n" << "monthlyInterestRate: " << saver1->getMonthlyInterest()
<< '\n' << "savingsBalance: " << saver1->getSavingsBalance() << '\n';
cout << "saver2\n" << "monthlyInterestRate: " << saver2->getMonthlyInterest()
<< '\n' << "savingsBalance: " << saver2->getSavingsBalance() << '\n';
}
On Visual Studio 2008, when I run my program, I get an output of "8192" before the data I want. Is there a reason for that?
Also, I don't think I am setting the fixed part or 2 decimal places correctly since I seem to get scientific notation once I added the setprecision(2). Thanks.
You want std::fixed (the other one just inserts its value into the stream, which is why you see 8192), and I don't see a call to std::setprecision in your code anywhere.
This'll fix it:
#include <iostream>
#include <iomanip>
using std::cout;
using std::setprecision;
using std::fixed;
int main()
{
cout << fixed << setprecision(2)
<< "saver1\n"
<< "monthlyInterestRate: " << 5.5 << '\n'
<< "savingsBalance: " << 10928.8383 << '\n';
cout << "saver2\n"
<< "monthlyInterestRate: " << 4.7 << '\n'
<< "savingsBalance: " << 22.44232 << '\n';
}
It might not be the answer you're looking for, but floating-point numbers are not suited to financial calculations because fractions like 1/100 cannot be represented exactly. You might be better off doing the formatting yourself. This can be encapsulated:
class money {
int cents;
public:
money( int in_cents ) : cents( in_cents ) {}
friend ostream &operator<< ( ostream &os, money const &rhs )
{ return os << '$' << m.cents / 100 << '.' << m.cents % 100; }
};
cout << money( 123 ) << endl; // prints $1.23
Better(?) yet, C++ has a facility called the monetary locale category which includes a money formatter which takes cents as an argument.
locale::global( locale("") );
use_facet< money_put<char> >( locale() ).put( cout, false, cout, ' ', 123 );
This should Do the Right thing internationally, printing the user's local currency and hiding the number of decimal places from your implementation. It even accepts fractions of a cent. Unfortunately, this does not seem to work on my system (Mac OS X), which has generally poor locale support. (Linux and Windows should fare better.)
cout << setiosflags(ios::fixed) << setprecision(2) << 1/3.;
ios_base::fixed is not manipulator it is a value (1 << 13) for the ios flag.

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';