Comment puis-je remplir un int avec des zéros en tête lorsque j'utilise l'opérateur cout <<? [dupliquer]

Réponses:

368

Avec ce qui suit,

#include <iomanip>
#include <iostream>

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

la sortie sera

00025

setfillest défini ' 'par défaut sur le caractère espace ( ). setwdéfinit la largeur du champ à imprimer, et c'est tout.


Si vous souhaitez savoir comment formater les flux de sortie en général, j'ai écrit une réponse à une autre question, j'espère que cela sera utile: Formatage de la sortie de la console C ++.

AraK
la source
3
mais .. comment puis-je écrire une sortie formatée dans une chaîne ( char* or char[]) pour ne pas console directement. En fait, j'écris une fonction qui renvoie une chaîne formatée
shashwat
12
@harsh use std :: stringstream
cheshirekow
8
n'oubliez pas de restaurer le format de flux après cela ou vous aurez une mauvaise surprise plus tard.
Code Abominator
14
Cette réponse m'a orienté dans la bonne direction mais elle pourrait être améliorée. Pour utiliser réellement ce code, vous devrez inclure <iostream>et <iomanip>en haut de votre fichier, et vous devrez écrire using namespace std;, mais c'est une mauvaise pratique, alors vous devriez peut-être plutôt préfixer les trois identificateurs de cette réponse std::.
David Grayson
@shashwat vous pouvez utiliser le code suivant - std :: stringstream filename; filename.fill ('0'); filename.width (5); nom de fichier << std :: to_string (i);
Prince Patel
45

Une autre façon d'y parvenir est d'utiliser l'ancienne printf()fonction du langage C

Vous pouvez l'utiliser comme

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

Cela s'imprimera 09 - 01 - 0001sur la console.

Vous pouvez également utiliser une autre fonction sprintf()pour écrire une sortie formatée dans une chaîne comme ci-dessous:

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

N'oubliez pas d'inclure le stdio.hfichier d'en - tête dans votre programme pour ces deux fonctions

A noter:

Vous pouvez remplir un espace vide soit par 0, soit par un autre caractère (pas un nombre).
Si vous écrivez quelque chose comme un %24dspécificateur de format, cela ne remplira pas 2les espaces vides. Cela définira le pad sur 24et remplira les espaces vides.

shashwat
la source
10
Je sais que c'est une vieille réponse, mais il convient de souligner que sprintf ne doit généralement pas trop faire confiance car vous ne pouvez pas spécifier la longueur du tampon dans lequel il est censé écrire. L'utilisation de snprintf a tendance à être plus sûre. L'utilisation de flux par opposition à * printf () est également beaucoup plus sûre pour le type car le compilateur a la possibilité de vérifier les types de paramètres au moment de la compilation; La réponse acceptée par AraK est à la fois sûre pour les types et C ++ "standard", et elle ne repose pas sur des en-têtes qui empoisonnent l'espace de noms global.
Magnus
La réponse utilise le formatage de la date comme exemple. Notez, cependant, qu'il utilise un format d'heure exotique comme exemple, même s'il semble similaire à ISO_8601 à la surface ( en.wikipedia.org/wiki/ISO_8601 ).
varepsilon
31
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

Cela produit la sortie:

-12345
****-12345
-12345****
****-12345
-****12345
quest333
la source
18
cout.fill( '0' );    
cout.width( 3 );
cout << value;
lyricat
la source
mais .. comment puis-je écrire une sortie formatée dans une chaîne ( char* or char[]) pour ne pas console directement. En fait, j'écris une fonction qui renvoie une chaîne formatée
shashwat
2
@Shashwat Tripathi Use std::stringstream.
AraK
@AraK Je pense que cela ne fonctionnerait pas dans Turbo C ++. Je l'ai utilisé en utilisant sprintf(s, "%02d-%02d-%04d", dd, mm, yy);sest char*et dd, mm, yysont de inttype. Cela écrira le 02-02-1999format en fonction des valeurs des variables.
shashwat
2

En C ++ 20 vous pourrez faire:

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

J'utiliserais la fonction suivante. Je n'aime pas sprintf; il ne fait pas ce que je veux !!

#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
la source
1

Un autre exemple pour afficher la date et l'heure en utilisant zéro comme caractère de remplissage sur les instances de valeurs à un chiffre: 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
la source