Как я могу дополнить int начальными нулями при использовании оператора cout <<? [Дубликат]

Ответы:

369

Со следующим,

#include <iomanip>
#include <iostream>

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

выход будет

00025

setfill' 'по умолчанию установлен на пробел ( ). setwустанавливает ширину поля для печати и все.


Если вам интересно узнать, как форматировать выходные потоки в целом, я написал ответ на другой вопрос, надеюсь, это будет полезно: Форматирование вывода на C ++.

арак
источник
3
но .. как я могу записать форматированный вывод в строку ( char* or char[]), а не на консоль напрямую. На самом деле я пишу функцию, которая возвращает отформатированную строку
shashwat
12
@harsh использование STD :: stringstream
cheshirekow
8
не забудьте восстановить формат потока после этого, иначе вы получите неприятный сюрприз.
Код Абоминатор
14
Этот ответ указал мне верное направление, но его можно улучшить. Чтобы на самом деле использовать этот код, вам нужно будет включить <iostream>и <iomanip>в начало вашего файла, и вам нужно будет написать using namespace std;, но это плохая практика, поэтому, возможно, вместо этого вы должны префикс трех идентификаторов в этом ответе с std::.
Дэвид Грейсон
@shashwat вы можете использовать следующий код - std :: stringstream filename; filename.fill ( '0'); filename.width (5); имя_файла << станд :: to_string (я);
Принц Патель
45

Еще один способ добиться этого - использовать старую printf()функцию языка Си

Вы можете использовать это как

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

Это напечатает 09 - 01 - 0001на консоли.

Вы также можете использовать другую функцию sprintf()для записи форматированного вывода в строку, как показано ниже:

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

Не забудьте включить stdio.hзаголовочный файл в вашу программу для обеих этих функций

Что следует отметить:

Вы можете заполнить пробел либо 0, либо другим символом (не числом).
Если вы напишите что-то вроде %24dспецификатора формата, это не будет заполнять 2пробелы. Это установит pad на 24и заполнит пустые места.

shashwat
источник
10
Я знаю, что это старый ответ, но все же следует указать, что sprintf обычно не следует слишком доверять, поскольку вы не можете указать длину буфера, в который он должен записывать. Использование snprintf обычно безопаснее. Использование потоков в отличие от * printf () также намного более безопасно для типов, потому что у компилятора есть возможность проверять типы параметров во время компиляции; Принятый ответ AraK - и безопасный тип, и «стандартный» C ++, и он не основан на заголовках, которые отравляют глобальное пространство имен.
Магнус
Ответ использует форматирование даты в качестве примера. Однако обратите внимание, что в качестве примера он использует экзотический формат времени, хотя на поверхности он выглядит аналогично 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

Это производит вывод:

-12345
****-12345
-12345****
****-12345
-****12345
quest333
источник
18
cout.fill( '0' );    
cout.width( 3 );
cout << value;
lyricat
источник
но .. как я могу записать форматированный вывод в строку ( char* or char[]), а не на консоль напрямую. На самом деле я пишу функцию, которая возвращает отформатированную строку
shashwat
2
@Shashwat Tripathi Использование std::stringstream.
АраК
@AraK Я думаю, что это не будет работать в Turbo C ++. Я использовал его , используя , sprintf(s, "%02d-%02d-%04d", dd, mm, yy);где sэто char*и dd, mm, yyимеют intтип. Это запишет 02-02-1999формат в соответствии со значениями в переменных.
shashwat
3

В C ++ 20 вы сможете делать:

std :: cout << std :: format ("{: 03}", 25); // печатает 025
Витовт
источник
1

Я бы использовал следующую функцию. Мне не нравится sprintf; это не делает то, что я хочу !!

#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;
}
Томас Дж. Юнси
источник
1

Другой пример вывода даты и времени с использованием нуля в качестве символа заполнения в случаях однозначных значений: 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
источник