如何在 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 < 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 < 0
,这种方法,代码将零放在"-"
之前。如果num > 999
,blankZeros[i] = '0';
溢出缓冲区。
感谢 @"chux - Reinstate Monica" 关于第一条评论。关于第二个,确实需要检查边界。以上是关于如何在 C sprintf 中添加用户定义的变量前导零?的主要内容,如果未能解决你的问题,请参考以下文章