Як я можу прокладати Int з провідними нулями при використанні оператора cout <<? [дублікат]


251

Я хочу coutвивести Int з провідними нулями, щоб значення 1було надруковано як, 001а значення 25надруковано як 025. Як я можу це зробити?

Відповіді:


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 use std :: stringstream
cheshirekow

8
не забудьте відновити формат потоку після цього, або пізніше ви отримаєте неприємний сюрприз.
Кодовий пагубник

14
Ця відповідь спрямовувала мене в правильному напрямку, але його можна було вдосконалити. Щоб фактично використовувати цей код, вам потрібно буде включити <iostream>і <iomanip>вгорі свого файлу, і вам потрібно буде написати using namespace std;, але це погана практика, тому, можливо, замість цього слід встановити префікс трьох ідентифікаторів у цій відповіді std::.
Девід Грейсон

@shashwat ви можете використовувати наступний код - std :: stringstream назва файлу; filename.fill ('0'); filename.width (5); ім'я файлу << std :: to_string (i);
Принц Патель

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порожні пробіли. Це встановить майданчик 24і заповнить порожні пробіли.


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

18
cout.fill( '0' );    
cout.width( 3 );
cout << value;

але .. як я можу записати відформатований вихід у рядок ( 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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.