【问题标题】:How can I pad an int with leading zeros when using cout << operator? [duplicate]使用 cout << 运算符时,如何用前导零填充 int? [复制]
【发布时间】:2021-12-17 07:23:39
【问题描述】:

我希望 cout 输出一个带前导零的 int,因此值 1 将打印为 001,值 25 打印为 025。我该怎么做?

【问题讨论】:

    标签: c++ formatting cout


    【解决方案1】:

    以下,

    #include <iomanip>
    #include <iostream>
    
    int main()
    {
        std::cout << std::setfill('0') << std::setw(5) << 25;
    }
    

    输出将是

    00025
    

    setfill 默认设置为空格字符 (' ')。 setw 设置要打印的字段的宽度,就是这样。


    如果您有兴趣了解如何格式化输出流,我为另一个问题写了一个答案,希望它有用: Formatting C++ Console Output.

    【讨论】:

    • 但是.. 我怎样才能将格式化输出写入字符串 (char* or char[]) 而不是直接控制台。实际上我正在编写一个返回格式化字符串的函数
    • @harsh 使用 std::stringstream
    • 完成后别忘了恢复流格式,否则你会得到一个令人讨厌的惊喜。
    • 这个答案为我指明了正确的方向,但可以改进。要实际使用此代码,您需要在文件顶部包含&lt;iostream&gt; 和&lt;iomanip&gt;,并且您需要编写using namespace std;,但这是不好的做法,因此您可能应该在这三个标识符前面加上前缀回复std::。
    • @shashwat 您可以使用以下代码 - std::stringstream 文件名;文件名.fill('0');文件名.width(5);文件名
    【解决方案2】:

    实现此目的的另一种方法是使用 C 语言的旧 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 并填充空格。

    【讨论】:

    • 我知道这是一个旧的答案,但仍然应该指出 sprintf 通常不应该被过度信任,因为你不能指定它应该写入的缓冲区的长度。使用 snprintf 往往更安全。使用流而不是 *printf() 也更安全,因为编译器有机会在编译时检查参数的类型; AraK 接受的答案既是类型安全又是“标准”C++,它不依赖于毒害全局命名空间的标头。
    • 答案是以日期格式为例。但是请注意,它使用了一种特殊的时间格式作为示例,尽管它表面上看起来类似于 ISO_8601 (en.wikipedia.org/wiki/ISO_8601)。
    • “你可以用 0 或另一个字符(不是数字)填充空白。” 似乎它只适用于零:ideone.com/vkwKxR。你能举个例子吗,如何使用其他字符?
    【解决方案3】:
    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
    

    【讨论】:

      【解决方案4】:

      在 C++20 中,您将能够做到:

      std::cout << std::format("{:03}", 25); // prints 025
      

      同时可以使用the {fmt} library,std::format是基于的。

      免责声明:我是 {fmt} 和 C++20 std::format 的作者。

      【讨论】:

      • 如果我理解正确,目前没有一个编译器支持这个?来源:en.cppreference.com/w/cpp/20
      • @jlh,这是一个库,不是编译器功能,否则你是对的:标准库实现还不支持 std::format (C++20 最近才发布)。我知道 libc++ 和 Microsoft 正在开发它。
      • 恭喜您的库进入 C++20!多年前第一次使用它。
      • @AlexOzer,谢谢!
      • 截至 2021 年 12 月,libc++ 和 Microsoft STL 具有 std::format 的部分实现,并且此示例适用于两者,例如godbolt.org/z/7MeqaEnc1
      【解决方案5】:
      cout.fill( '0' );    
      cout.width( 3 );
      cout << value;
      

      【讨论】:

      • 但是.. 我怎样才能将格式化输出写入字符串 (char* or char[]) 而不是直接控制台。实际上我正在编写一个返回格式化字符串的函数
      • @Shashwat Tripathi 使用 std::stringstream.
      • @AraK 我认为这在 Turbo C++ 中不起作用。我使用sprintf(s, "%02d-%02d-%04d", dd, mm, yy); 使用它,其中s 是char* 和dd, mm, yy 是int 类型。这将根据变量中的值写入02-02-1999格式。
      【解决方案6】:

      另一个使用零作为单个数字值实例的填充字符输出日期和时间的示例: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;
      }
      

      【讨论】:

        【解决方案7】:

        我会使用以下功能。我不喜欢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;
        }
        

        【讨论】:

          猜你喜欢
          • 2014-04-25
          • 2011-10-09
          • 2011-03-28
          • 2010-11-19
          • 2014-02-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多