Jak wstawić liczbę całkowitą z wiodącymi zerami, używając operatora cout <<? [duplikować]

Odpowiedzi:

369

Z następującymi,

#include <iomanip>
#include <iostream>

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

wyjście będzie

00025

setfilljest ustawiony ' 'domyślnie na znak spacji ( ). setwustawia szerokość pola do wydrukowania i to wszystko.


Jeśli chcesz dowiedzieć się, jak ogólnie sformatować strumienie wyjściowe, napisałem odpowiedź na inne pytanie, mam nadzieję, że się przyda: Formatowanie wyjścia konsoli C ++.

ARAK
źródło
3
ale .. jak mogę zapisać sformatowane dane wyjściowe w ciągu ( char* or char[]), aby nie konsolować bezpośrednio. Właściwie piszę funkcję, która zwraca sformatowany ciąg
shashwat,
12
@harsh use std :: stringstream
cheshirekow
8
nie zapomnij przywrócić formatu strumienia po wykonaniu tej czynności, w przeciwnym razie otrzymasz paskudną niespodziankę.
Kod Abominator
14
Ta odpowiedź wskazała mi właściwy kierunek, ale można ją poprawić. Aby faktycznie użyć tego kodu, musisz dołączyć <iostream>i <iomanip>na górze pliku, i będziesz musiał napisać using namespace std;, ale to zła praktyka, więc może zamiast tego powinieneś poprzedzić trzy identyfikatory w tej odpowiedzi std::.
David Grayson,
@shashwat możesz użyć następującego kodu - std :: stringstream filename; nazwa_pliku.fill („0”); nazwa_pliku.width (5); nazwa pliku << std :: to_string (i);
Prince Patel,
45

Innym sposobem na osiągnięcie tego jest użycie starej printf()funkcji języka C.

Możesz użyć tego jak

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

Zostanie wydrukowane 09 - 01 - 0001na konsoli.

Możesz także użyć innej funkcji, sprintf()aby zapisać sformatowane dane wyjściowe w ciągu znaków, jak poniżej:

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

Nie zapomnij dołączyć stdio.hpliku nagłówka do swojego programu dla obu tych funkcji

Rzecz, na którą należy zwrócić uwagę:

Możesz wypełnić puste miejsce 0 lub innym znakiem (nie liczbą).
Jeśli napiszesz coś w rodzaju %24dspecyfikatora formatu, nie spowoduje to wypełnienia 2pustych miejsc. Spowoduje to ustawienie padu 24i wypełnienie pustych miejsc.

shashwat
źródło
10
Wiem, że to stara odpowiedź, ale wciąż należy zauważyć, że sprintf nie powinien być zbytnio zaufany, ponieważ nie można określić długości bufora, do którego ma pisać. Korzystanie z snprintf jest zwykle bezpieczniejsze. Używanie strumieni w przeciwieństwie do * printf () jest również znacznie bardziej bezpieczne dla typów, ponieważ kompilator ma szansę sprawdzić typy parametrów w czasie kompilacji; Akceptowana odpowiedź AraK jest zarówno bezpieczna dla typu, jak i „standardowa” C ++ i nie opiera się na nagłówkach, które zatruwają globalną przestrzeń nazw.
Magnus
W odpowiedzi użyto formatowania daty jako przykładu. Zauważ jednak, że używa przykładowego egzotycznego formatu czasu, mimo że na powierzchni wygląda podobnie do ISO_8601 ( 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

To daje wynik:

-12345
****-12345
-12345****
****-12345
-****12345
quest333
źródło
18
cout.fill( '0' );    
cout.width( 3 );
cout << value;
lyricat
źródło
ale .. jak mogę zapisać sformatowane dane wyjściowe w ciągu ( char* or char[]), aby nie konsolować bezpośrednio. Właściwie piszę funkcję, która zwraca sformatowany ciąg
shashwat,
2
@Shashwat Tripathi Use std::stringstream.
AraK,
@AraK Myślę, że to nie zadziała w Turbo C ++. Użyłem go, sprintf(s, "%02d-%02d-%04d", dd, mm, yy);gdzie sjest char*i dd, mm, yyjest inttypu. Spowoduje to zapisanie 02-02-1999formatu zgodnie z wartościami w zmiennych.
shashwat
3

W C ++ 20 będziesz mógł:

std :: cout << format std :: ("{: 03}", 25); // drukuje 025
vitaut
źródło
1

Chciałbym użyć następującej funkcji. Nie lubie sprintf; nie robi tego, co chcę !!

#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
źródło
1

Kolejny przykład wyświetlania daty i godziny za pomocą zera jako znaku wypełniającego w wystąpieniach wartości jednocyfrowych: 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;
}
użytkownik 8163172
źródło