如何在 C sprintf 中添加用户定义的变量前导零?

Posted

技术标签:

【中文标题】如何在 C sprintf 中添加用户定义的变量前导零?【英文标题】:How to add user defined variable leading zeros in 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

现在,我的主要问题是,

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

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

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

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

【问题讨论】:

@S.M.这段代码似乎比下面 Paul 编写的代码更容易,但是,我不能在这里勾选你的答案 :) 如果num = -5,预期的输出是什么? "-005""-05" 还是什么? 【参考方案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】:
    如果否,是否有任何其他方法可以执行相同的操作以获得所需的输出?

如果你还是要将结果输出到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" 关于第一条评论。关于第二个,确实需要检查边界。

以上是关于如何在 C sprintf 中添加用户定义的变量前导零?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 sprintf 函数在字符中添加前导“0”而不是空格?

sprintf函数的用法是啥?

C语言 sprintf函数,如何生成不规则的随机字符串?

如何使用sprintf格式化R中数据框的打印?

sprintf()函数的用法

sprintf在C中引领零填充