Rate this page

Pad an integer with leading zeros in C++

Tested on

Ubuntu (Lucid, Precise)


To pad an integer with leading zeros to a given minimum width when converting it to a character string in C++


Suppose you are writing a program for generating customer invoices. Each customer has an account number. These are represented internally as integers, but when converted to character strings for display or printing you want them to be padded to 8 digits using leading zeros.


The method described here uses the C++ iostream library to perform the conversion. It requires an output stream for the result to be sent to, however a std::ostringstream can be used to capture the character sequence and present it as a std::string if required. Padding with zeros is achieved by combining the effect of three standard manipulators:

The required header files are:

Header Used by
<ios> std::internal
<iomanip> std::setw, std::setfill
<sstream> std::ostringstream

If you are using a std::ostringstream that will be discarded immediately after the conversion then simply write the three manipulators to the stream (in any order) followed by the value to be converted:

std::string format_account_number(int acct_no) {
  ostringstream out;
  out << std::internal << std::setfill('0') << std::setw(8) << acct_no;
  return out.str();

If the stream will be used subsequently for other purposes then you will probably want to reset the fill character and field adjustment properties, otherwise they will remain in effect for later output. It is not necessary to do this for the field width, which is automatically reset to zero after each field is written:

void write_account_number(std::ostream& out, int acct_no) {
  out << std::internal << std::setfill('0') << std::setw(8) << acct_no;
  out << std::left << std::setfill(' ');

The std::internal manipulator can be omitted if the number is unsigned or known to be non-negative, but it is needed in the general case because because otherwise the padding characters will be inserted at the far left of the field by default (producing output such as 000000-1 as opposed to -0000001).

Be aware that because std::setw controls the total width of the field (including the sign if there is one), with the consequence that negative values will by default be one digit shorter than non-negative values. If this is a problem then std::showpos can be used to ensure that there is always a sign (plus or minus), in which case the number of digits remains constant.

Floating point values can be padded in a similar manner. The same applies to character strings, except that std::internal would be ineffective.


Using sprintf

A similar effect can be achieved using std::snprintf from <cstdio>:

std::string format_account_number(int acct_no) {
  char buffer[9];
  std::snprintf(buffer, sizeof(buffer), "%08d", acct_no);
  return buffer;

For a typical implementation of the standard library this method is likely to be significantly faster than using a std::ostringstream (and would be faster still if std::string were avoided too). The cost is that buffer management and type safety become your responsibility, with undefined behaviour the likely consequence if you make a mistake.

A minor difference is that std::snprintf will truncate to whatever buffer length you have chosen, whereas std::ostringstream will not.

Tags: c++