79

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;
jww
  • 97,681
  • 90
  • 411
  • 885
Frank
  • 64,140
  • 93
  • 237
  • 324

6 Answers6

115

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 :-)

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • 2
    Note that you can also just use `cout << left` or `cout << right` for alignment. – Dan Moulding Dec 09 '09 at 15:43
  • Note that this solution does NOT work correctly for negative numbers! Trying to print "-5" this way results in: "000-5" – Nadav Har'El Apr 03 '19 at 11:45
  • Adding std::internal will make this code correct for negative numbers. – Nadav Har'El Apr 03 '19 at 11:53
  • 2
    @Nadav, do you live in an area that has negative ZIP codes? :-) On a more serious note, I'll edit the answer to make that clear. – paxdiablo Apr 04 '19 at 00:55
  • 1
    Thanks. I actually found your answer looking for a general solution for any integer, including negatives, found your nice highly-ranked answer and I didn't realize that because zip codes were mentioned, the answer assumed the integer was positive. Thanks for editing the answer, it will probably help more people in the future. – Nadav Har'El Apr 04 '19 at 14:34
14

Use the setw and setfill calls:

std::cout << std::setw(5) << std::setfill('0') << zipCode << std::endl;
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
Nik Reiman
  • 39,067
  • 29
  • 104
  • 160
  • Re-activated and +1'ed since it shows how to do it in any namespace (also added setfill, sqook, hope you don't mind). – paxdiablo Feb 10 '09 at 02:21
  • Fair enough. "using namespace std;" is definitely evil. ;) – Nik Reiman Feb 10 '09 at 02:29
  • 1
    I think this answer should mention that, unlike the setting from `std::setw`, the setting of `std::setfill` will stick after the output is performed, in other words the fill character for `std::cout` will be permanently changed (until modified by another `std::setfill`). As it is unlikely this is desirable, it would seem best to save and restore the previous fill character. – Marc van Leeuwen May 18 '17 at 07:18
13

In C++20 you can do:

std::cout << std::format("{:05}", zipCode);

On older systems you can use the {fmt} library, std::format is based on.

Disclaimer: I'm the author of {fmt} and C++20 std::format.

vitaut
  • 49,672
  • 25
  • 199
  • 336
5
cout << setw(4) << setfill('0') << n << endl;

from:

http://www.fredosaurus.com/notes-cpp/io/omanipulators.html

anthony
  • 40,424
  • 5
  • 55
  • 128
2

or,

char t[32];
sprintf_s(t, "%05d", 1);

will output 00001 as the OP already wanted to do

Jason Newland
  • 481
  • 5
  • 3
0

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;
 }
A P
  • 2,131
  • 2
  • 24
  • 36