【问题标题】:How to add user defined variable leading zeros in C sprintf?如何在 C sprintf 中添加用户定义的变量前导零?
【发布时间】:2022-01-21 08:18:23
【问题描述】:

我正在开发一个程序,我需要为 3 个数字添加前导零

所以代码看起来像这样

#include <iostream>
using namespace std;

// Check Examples


//Compiler version g++ 6.3.0

int main()
{
    
    long int num =5;
    
    char CNum[10];
    
    sprintf(CNum,"%03ld",num) ;
    
    std::cout << CNum;
    
    return 0;
}

// Outputs 005

现在让我们在一个名为的整数变量中定义前导零的个数

int blank = 3

之后的代码应该是这样的

#include <iostream>
using namespace std;

// Check Examples


//Compiler version g++ 6.3.0

int main()
{
    int blank = 3;
    long int num =5;
    
    char CNum[10];
    
    sprintf(CNum,"%03ld",num) ;
    
    std::cout << CNum;
    
    return 0;
}

然后我像这样编辑了 sprintf 参数

sprintf(CNum,"%0%dld",blank,num);

这个输出

%dld

而不是

005

现在,我的主要问题是,

  1. 我可以像这样在 sprintf 中添加用户变量定义的前导零吗?

    1. 如果是,我怎样才能让我的代码做到这一点?

    2. 如果否,是否有任何其他方法可以执行相同的操作以获得所需的输出?

谢谢您,期待您的热情回复...

【问题讨论】:

  • @S.M.这段代码似乎比下面 Paul 编写的代码更容易,但是,我不能在这里勾选你的答案 :)
  • 如果num = -5,预期的输出是什么? "-005""-05" 还是什么?

标签: c++ integer printf


【解决方案1】:

如果想要输出至少 3 个字符,请根据需要使用 '0' 填充 @j6t

sprintf(CNum,"%0*ld", blank, num);

如果想要输出至少 3 个数字,请根据需要使用'0' 填充:

sprintf(CNum,"%0.*ld", blank, num);

num &lt; 0 时输出不同。


使用sprintf()容易出现缓冲区溢出。

可以使用snprintf() 或更多沿@BoP 的C++ 行。

【讨论】:

    【解决方案2】:

    一种简单而灵活的方法是在运行时构造自己的格式字符串,例如:

    #include <iostream>
    #include <string>
    
    int main ()
    {
        long int num = 5;
        int n_zeroes = 3;
        
        std::string fmt = "%0" + std::to_string (n_zeroes) + "ld";
        
        char CNum [10];
        sprintf (CNum, fmt.c_str (), num) ;
        
        std::cout << CNum;
    }    
    

    Live demo

    【讨论】:

    • 你的答案也不错
    【解决方案3】:

    要使宽度动态化(不是在格式字符串中硬编码),你可以这样写:

    sprintf(CNum,"%0*ld",blank,num); 
    

    "%03ld" 中的硬编码宽度3 不同,将下一个参数(必须为int 类型)作为宽度的asterisk indicates

    【讨论】:

    • 好吧,我想我是第一次看到这样使用星号,请原谅,请问星号是干什么用的?
    • 我扩展了答案。
    【解决方案4】:
    1. 如果否,是否有任何其他方法可以执行相同的操作以获得所需的输出?

    如果你还是要将结果输出到cout,你可以直接在那里进行格式化:

    std::cout << std::setfill('0') << std::setw(blank) << num;
    

    【讨论】:

      【解决方案5】:

      试着理解下面的代码——它会解决你的问题:

      #include <iostream>
      #include <string.h>
      using namespace std;
      // Check Examples
      
      //Compiler version g++ 6.3.0
      
      int main()
      {
          int blank = 3;
          long int num =5;
          unsigned int i = 0;
      
          char blankZeros[16];
          char numStr[16];
          char CNum[16];
      
          sprintf(numStr,"%ld",num);
          for (i = 0; i < blank - strlen(numStr); i++)
              blankZeros[i] = '0';        // adding a zero
          blankZeros[i++] = '\0';         // end of string sign
      
          sprintf(CNum,"%s%s",blankZeros, numStr) ;
      
          std::cout << CNum;
      
          return 0;
      }
      

      【讨论】:

      • 你的代码也不错,但是很复杂,最重要的是你的代码很大。
      • 感谢您的评论,尽管我不同意这个复杂的问题。 @Paul Sanders 的代码,例如不像我那样高效,因为它使用的是字符串连接,与我的相比要慢得多。 sprintf() 也是取自 C 库而不是 C++
      • 代码可以使用sprintf()的返回值,而不是strlen(numStr)int len = sprintf(numStr,"%ld",num);
      • num &lt; 0,这种方法,代码将零放在"-"之前。如果num &gt; 999blankZeros[i] = '0'; 溢出缓冲区。
      • 感谢 @"chux - Reinstate Monica" 关于第一条评论。关于第二个,确实需要检查边界。
      猜你喜欢
      • 1970-01-01
      • 2015-04-28
      • 2021-11-21
      • 2011-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-26
      相关资源
      最近更新 更多