How can I pad an int with leading zeros when using cout << operator? [duplicate]
Asked Answered
S

7

323

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?

Spigot answered 11/11, 2009 at 11:12 Comment(0)
K
485

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.

Kwa answered 11/11, 2009 at 11:16 Comment(8)
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 stringQuoit
@harsh use std::stringstreamAnsel
don't forget to restore the stream format after doing that or you'll get a nasty surprise later.Southerly
This answer pointed me in the right direction but it could be improved. To actually use this code, you will need to include <iostream> and <iomanip> 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::.Hizar
@Quoit you can use following code - std::stringstream filename; filename.fill('0'); filename.width(5); filename<<std::to_string(i);Stephanistephania
@CodeAbominator what is the best way to do this? With "best" meaning requiring least keystrokes.Caretaker
#2273830Southerly
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.Soil
Q
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.

Quoit answered 23/12, 2012 at 12:54 Comment(4)
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.Viperine
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 (en.wikipedia.org/wiki/ISO_8601).Statutory
"You can fill blank space either by 0 or by another char (not number)." Seems like it works only with zero: ideone.com/vkwKxR. Can you give an example, how to use any other char?Preposition
This doesn't answer what was asked.Vertumnus
U
43
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
Undercarriage answered 12/10, 2014 at 9:27 Comment(0)
C
32

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.

Colcannon answered 25/6, 2020 at 14:57 Comment(4)
If I understand correctly, not a single compiler currently supports this? Source: en.cppreference.com/w/cpp/20Pronation
@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.Colcannon
Congrats on getting your library into C++20! First used it many years ago.Interstice
As of December 2021, libc++ and Microsoft STL have partial implementations of std::format and this example works in both e.g. godbolt.org/z/7MeqaEnc1Colcannon
H
18
cout.fill( '0' );    
cout.width( 3 );
cout << value;
Hieratic answered 11/11, 2009 at 11:17 Comment(3)
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 stringQuoit
@Shashwat Tripathi Use std::stringstream.Kwa
@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.Quoit
S
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;
}
Starlet answered 14/6, 2017 at 23:3 Comment(0)
A
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;
}
Ansela answered 15/3, 2013 at 2:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.