¿Cómo puedo rellenar un int con ceros a la izquierda cuando uso el operador cout <<?

Respuestas:

369

Con lo siguiente,

#include <iomanip>
#include <iostream>

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

la salida será

00025

setfillestá configurado con el carácter de espacio ( ' ') de forma predeterminada. setwestablece el ancho del campo a imprimir, y eso es todo.


Si está interesado en saber cómo formatear las secuencias de salida en general, escribí una respuesta para otra pregunta, espero que sea útil: Formatear la salida de la consola C ++.

AraK
fuente
3
pero ... ¿cómo puedo escribir una salida formateada en una cadena ( char* or char[]) para no consolar directamente? En realidad, estoy escribiendo una función que devuelve una cadena con formato
shashwat
12
@harsh use std :: stringstream
cheshirekow
8
No olvide restaurar el formato de transmisión después de hacerlo o obtendrá una desagradable sorpresa más tarde.
Code Abominator
14
Esta respuesta me señaló en la dirección correcta, pero podría mejorarse. Para usar realmente este código, deberá incluir <iostream>y <iomanip>en la parte superior de su archivo, y deberá escribir using namespace std;, pero esa es una mala práctica, por lo que tal vez debería prefijar los tres identificadores en esta respuesta con std::.
David Grayson
@shashwat puede usar el siguiente código: std :: stringstream filename; filename.fill ('0'); filename.width (5); nombre de archivo << std :: to_string (i);
Príncipe Patel
45

Otra forma de lograr esto es usar la printf()función antigua del lenguaje C

Puedes usar esto como

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

Esto se imprimirá 09 - 01 - 0001en la consola.

También puede usar otra función sprintf()para escribir resultados formateados en una cadena como la siguiente:

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

No olvide incluir el stdio.harchivo de encabezado en su programa para ambas funciones

Cosa a tener en cuenta:

Puede llenar el espacio en blanco ya sea por 0 o por otro carácter (no número).
Si escribe algo como un %24despecificador de formato, esto no rellenará 2espacios en blanco. Esto establecerá el pad en 24y llenará los espacios en blanco.

shashwat
fuente
10
Sé que esta es una respuesta antigua, pero aún debe señalarse que generalmente no se debe confiar demasiado en sprintf ya que no se puede especificar la longitud del búfer en el que se supone que debe escribir. Usar snprintf tiende a ser más seguro. El uso de secuencias en lugar de * printf () también es mucho más seguro para los tipos porque el compilador tiene la oportunidad de verificar los tipos de parámetros en tiempo de compilación; La respuesta aceptada de AraK es C ++ seguro de tipo y "estándar", y no se basa en encabezados que envenenan el espacio de nombres global.
Magnus
La respuesta está usando el formato de fecha como ejemplo. Sin embargo, tenga en cuenta que está usando un formato de tiempo exótico como ejemplo, a pesar de que se ve similar a ISO_8601 en la superficie ( en.wikipedia.org/wiki/ISO_8601 ).
varepsilon
32
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

Esto produce la salida:

-12345
****-12345
-12345****
****-12345
-****12345
quest333
fuente
18
cout.fill( '0' );    
cout.width( 3 );
cout << value;
lyricat
fuente
pero ... ¿cómo puedo escribir una salida formateada en una cadena ( char* or char[]) para no consolar directamente? En realidad estoy escribiendo una función que devuelve cadena con formato
Shashwat
2
@Shashwat Tripathi Use std::stringstream.
AraK
@AraK Creo que esto no funcionaría en Turbo C ++. Lo usé usando sprintf(s, "%02d-%02d-%04d", dd, mm, yy);where sis char*y dd, mm, yyare of inttype. Esto escribirá el 02-02-1999formato de acuerdo con los valores en las variables.
shashwat
2

Yo usaría la siguiente función. Yo no como hago sprintf; no hace lo que quiero !!

#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;
}
Thomas J Younsi
fuente
2

Otro ejemplo para generar la fecha y la hora usando cero como carácter de relleno en instancias de valores de un solo dígito: 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;
}
usuario8163172
fuente
0

En C ++ 20 podrás hacer:

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