315

I want cout to output an int with leading zeros, so the value 1 would be printed as 001 and the value 25 printed as 025. How can I do this?

royhowie
  • 11,075
  • 14
  • 50
  • 67
jamieQ
  • 3,215
  • 3
  • 18
  • 6

7 Answers7

468

With the following,

#include <iomanip>
#include <iostream>

int main()
{
    std::cout << std::setfill('0') << std::setw(5) << 25;
}

the output will be

00025

setfill is set to the space character (' ') by default. setw sets the width of the field to be printed, and that's it.


If you are interested in knowing how the to format output streams in general, I wrote an answer for another question, hope it is useful: Formatting C++ Console Output.

DevSolar
  • 67,862
  • 21
  • 134
  • 209
Khaled Alshaya
  • 94,250
  • 39
  • 176
  • 234
  • 5
    but.. how can I write formatted output to a string (`char* or char[]`) not to console directly. Actually I am writing a function that returns formatted string – shashwat Dec 23 '12 at 09:32
  • 19
    @harsh use std::stringstream – cheshirekow Apr 30 '13 at 14:51
  • 10
    don't forget to restore the stream format after doing that or you'll get a nasty surprise later. – Code Abominator Apr 15 '15 at 00:03
  • 17
    This answer pointed me in the right direction but it could be improved. To actually use this code, you will need to include `` and `` at the top of your file, and you will need to write `using namespace std;`, but that's bad practice so maybe instead you should prefix the three identifiers in this answer with `std::`. – David Grayson Jul 06 '15 at 17:44
  • @shashwat you can use following code - std::stringstream filename; filename.fill('0'); filename.width(5); filename< – Prince Patel Feb 25 '19 at 16:14
  • @CodeAbominator what is the best way to do this? With "best" meaning requiring least keystrokes. – iko79 Mar 19 '20 at 09:32
  • https://stackoverflow.com/questions/2273330/restore-the-state-of-stdcout-after-manipulating-it – Code Abominator Mar 19 '20 at 23:27
  • 6
    Just to add to the fun, `std::setw` sets the width property of the stream only until the next output operation, after which it's reset to 0, but `std::setfill` is persistent. – Keith Thompson Mar 26 '22 at 04:36
57

Another way to achieve this is using old printf() function of C language

You can use this like

int dd = 1, mm = 9, yy = 1;
printf("%02d - %02d - %04d", mm, dd, yy);

This will print 09 - 01 - 0001 on the console.

You can also use another function sprintf() to write formatted output to a string like below:

int dd = 1, mm = 9, yy = 1;
char s[25];
sprintf(s, "%02d - %02d - %04d", mm, dd, yy);
cout << s;

Don't forget to include stdio.h header file in your program for both of these functions

Thing to be noted:

You can fill blank space either by 0 or by another char (not number).
If you do write something like %24d format specifier than this will not fill 2 in blank spaces. This will set pad to 24 and will fill blank spaces.

shashwat
  • 7,851
  • 9
  • 57
  • 90
  • 13
    I know this is an old answer, but it should still be pointed out that sprintf should generally not be trusted too much since you can't specify the length of the buffer it's supposed to write to. Using snprintf tends to be safer. Using streams as opposed to *printf() is also much more type safe because the compiler has a chance to check the parameters' types at compile time; AraK's accepted answer is both type safe and "standard" C++, and it doesn't rely on headers that poison the global namespace. – Magnus Feb 05 '14 at 14:19
  • The answer is using date formatting as an example. Note, however, that it's using an exotic time format as an example, even though it looks similar to ISO_8601 on the surface (https://en.wikipedia.org/wiki/ISO_8601). – varepsilon Apr 15 '19 at 12:04
  • _"You can fill blank space either by 0 or by another char (not number)."_ Seems like it works only with zero: https://ideone.com/vkwKxR. Can you give an example, how to use any other char? – Qwertiy Oct 25 '21 at 09:46
  • This doesn't answer what was asked. – Jason Aug 30 '23 at 21:01
41
cout.fill('*');
cout << -12345 << endl; // print default value with no field width
cout << setw(10) << -12345 << endl; // print default with field width
cout << setw(10) << left << -12345 << endl; // print left justified
cout << setw(10) << right << -12345 << endl; // print right justified
cout << setw(10) << internal << -12345 << endl; // print internally justified

This produces the output:

-12345
****-12345
-12345****
****-12345
-****12345
Itay Grudev
  • 7,055
  • 4
  • 54
  • 86
quest333
  • 419
  • 4
  • 2
31

In C++20 you can do:

std::cout << std::format("{:03}", 25); // prints 025

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.

vitaut
  • 49,672
  • 25
  • 199
  • 336
  • If I understand correctly, not a single compiler currently supports this? Source: https://en.cppreference.com/w/cpp/20 – jlh Dec 31 '20 at 16:46
  • 2
    @jlh, this is a library, not compiler feature but otherwise you are right: std::format is not supported by standard library implementations yet (C++20 has only recently been published). I know that libc++ and Microsoft work on it. – vitaut Dec 31 '20 at 19:32
  • 3
    Congrats on getting your library into C++20! First used it many years ago. – Alex Ozer Apr 14 '21 at 23:10
  • As of December 2021, libc++ and Microsoft STL have partial implementations of std::format and this example works in both e.g. https://godbolt.org/z/7MeqaEnc1 – vitaut Dec 24 '21 at 16:09
18
cout.fill( '0' );    
cout.width( 3 );
cout << value;
lyricat
  • 1,988
  • 2
  • 12
  • 20
  • but.. how can I write formatted output to a string (`char* or char[]`) not to console directly. Actually I am writing a function that returns formatted string – shashwat Dec 23 '12 at 09:33
  • 2
    @Shashwat Tripathi Use `std::stringstream`. – Khaled Alshaya Dec 23 '12 at 10:19
  • @AraK I think this would not work in Turbo C++. I used it using `sprintf(s, "%02d-%02d-%04d", dd, mm, yy);` where `s` is `char*` and `dd, mm, yy` are of `int` type. This will write `02-02-1999` format according to the values in variables. – shashwat Dec 23 '12 at 12:44
3

Another example to output date and time using zero as a fill character on instances of single digit values: 2017-06-04 18:13:02

#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <ctime>
using namespace std;

int main()
{
    time_t t = time(0);   // Get time now
    struct tm * now = localtime(&t);
    cout.fill('0');
    cout << (now->tm_year + 1900) << '-'
        << setw(2) << (now->tm_mon + 1) << '-'
        << setw(2) << now->tm_mday << ' '
        << setw(2) << now->tm_hour << ':'
        << setw(2) << now->tm_min << ':'
        << setw(2) << now->tm_sec
        << endl;
    return 0;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
1

I would use the following function. I don't like sprintf; it doesn't do what I want!!

#define hexchar(x)    ((((x)&0x0F)>9)?((x)+'A'-10):((x)+'0'))
typedef signed long long   Int64;

// Special printf for numbers only
// See formatting information below.
//
//    Print the number "n" in the given "base"
//    using exactly "numDigits".
//    Print +/- if signed flag "isSigned" is TRUE.
//    Use the character specified in "padchar" to pad extra characters.
//
//    Examples:
//    sprintfNum(pszBuffer, 6, 10, 6,  TRUE, ' ',   1234);  -->  " +1234"
//    sprintfNum(pszBuffer, 6, 10, 6, FALSE, '0',   1234);  -->  "001234"
//    sprintfNum(pszBuffer, 6, 16, 6, FALSE, '.', 0x5AA5);  -->  "..5AA5"
void sprintfNum(char *pszBuffer, int size, char base, char numDigits, char isSigned, char padchar, Int64 n)
{
    char *ptr = pszBuffer;

    if (!pszBuffer)
    {
        return;
    }

    char *p, buf[32];
    unsigned long long x;
    unsigned char count;

    // Prepare negative number
    if (isSigned && (n < 0))
    {
        x = -n;
    }
    else
    {
        x = n;
    }

    // Set up small string buffer
    count = (numDigits-1) - (isSigned?1:0);
    p = buf + sizeof (buf);
    *--p = '\0';

    // Force calculation of first digit
    // (to prevent zero from not printing at all!!!)
    *--p = (char)hexchar(x%base);
    x = x / base;

    // Calculate remaining digits
    while(count--)
    {
        if(x != 0)
        {
            // Calculate next digit
            *--p = (char)hexchar(x%base);
            x /= base;
        }
        else
        {
            // No more digits left, pad out to desired length
            *--p = padchar;
        }
    }

    // Apply signed notation if requested
    if (isSigned)
    {
        if (n < 0)
        {
            *--p = '-';
        }
        else if (n > 0)
        {
            *--p = '+';
        }
        else
        {
            *--p = ' ';
        }
    }

    // Print the string right-justified
    count = numDigits;
    while (count--)
    {
        *ptr++ = *p++;
    }
    return;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131