Como posso preencher um int com zeros à esquerda ao usar o operador cout <<?

248

Eu quero coutgerar um int com zeros à esquerda, para que o valor 1seja impresso como 001e o valor 25impresso como 025. Como posso fazer isso?

jamieQ
fonte
2
possível duplicação dos zeros à esquerda
atoMerz

Respostas:

369

Com o seguinte,

#include <iomanip>
#include <iostream>

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

a saída será

00025

setfillé definido como o caractere de espaço ( ' ') por padrão. setwdefine a largura do campo a ser impresso, e é isso.


Se você estiver interessado em saber como formatar os fluxos de saída em geral, escrevi uma resposta para outra pergunta, espero que seja útil: Formatando a Saída do Console C ++.

AraK
fonte
3
mas .. como posso escrever saída formatada em uma string ( char* or char[]) para não console diretamente. Na verdade eu estou escrevendo uma função que retorna formatado seqüência
Shashwat
12
@harsh use std :: stringstream
cheshirekow
8
não se esqueça de restaurar o formato do fluxo depois de fazer isso ou você terá uma surpresa desagradável mais tarde.
Code Abominator
14
Essa resposta me apontou na direção certa, mas poderia ser melhorada. Para realmente usar esse código, você precisará incluir <iostream>e <iomanip>na parte superior do seu arquivo, e precisará escrever using namespace std;, mas isso é uma prática inadequada; portanto, talvez prefira os três identificadores nesta resposta std::.
David Grayson
@shashwat você pode usar o seguinte código - std :: stringstream filename; filename.fill ('0'); filename.width (5); nome do arquivo << std :: to_string (i);
Prince Patel
45

Outra maneira de conseguir isso é usar a printf()função antiga da linguagem C

Você pode usar isso como

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

Isso será impresso 09 - 01 - 0001no console.

Você também pode usar outra função sprintf()para gravar saída formatada em uma string como abaixo:

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

Não se esqueça de incluir o stdio.harquivo de cabeçalho no seu programa para essas duas funções

Coisa a ser notada:

Você pode preencher o espaço em branco por 0 ou por outro caractere (não número).
Se você escrever algo como um %24despecificador de formato, isso não preencherá 2espaços em branco. Isso definirá o bloco 24e preencherá os espaços em branco.

shashwat
fonte
10
Eu sei que essa é uma resposta antiga, mas ainda deve ser destacado que o sprintf geralmente não deve ser confiável demais, pois você não pode especificar o tamanho do buffer no qual ele deve gravar. Usar snprintf tende a ser mais seguro. Usar fluxos em oposição a * printf () também é muito mais seguro para tipos, porque o compilador tem a chance de verificar os tipos de parâmetros em tempo de compilação; A resposta aceita do AraK é do tipo seguro e C ++ "padrão" e não depende de cabeçalhos que envenenam o espaço de nomes global.
Magnus
A resposta está usando a formatação de data como exemplo. Observe, no entanto, que ele está usando um formato de hora exótico como exemplo, mesmo que pareça com ISO_8601 na superfície ( 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

Isso produz a saída:

-12345
****-12345
-12345****
****-12345
-****12345
quest333
fonte
18
cout.fill( '0' );    
cout.width( 3 );
cout << value;
lyricat
fonte
mas .. como posso escrever saída formatada em uma string ( char* or char[]) para não console diretamente. Na verdade eu estou escrevendo uma função que retorna formatado seqüência
Shashwat
2
@Shashwat Tripathi Use std::stringstream.
23412 AraK
@ Ark Acho que isso não iria funcionar no Turbo C ++. Eu usei usando sprintf(s, "%02d-%02d-%04d", dd, mm, yy);where sis char*e dd, mm, yyare do inttipo. Isso escreverá o 02-02-1999formato de acordo com os valores nas variáveis.
Shashwat
3

Eu usaria a seguinte função. Eu não gosto sprintf; não faz o que eu quero !!

#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
fonte
2

Outro exemplo para gerar data e hora usando zero como caractere de preenchimento em instâncias de valores de um 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;
}
user8163172
fonte