在C语言中如何打印前导0

414

我想找到一个好的方法来打印前导 0,例如邮政编码中的01001。虽然该数字将被存储为1001,但有什么好的方法可以做到这一点呢?

我考虑使用case语句或if语句来确定数字的位数,然后将其转换为带有额外0char数组以进行打印,但我不禁想知道是否有一种使用printf格式语法的方法可以实现此目的。


这个怎么样?https://dev59.com/unRB5IYBdhLWcg3wvpic#71541766 - A P
@AviPars:您建议使用C++解决方案:std::cout << std::setw(5) << std::setfill('0') << zipCode << std::endl;,这是一种类型安全但工作量巨大的替代方案,可以替换为printf("%05\n", (int)zipCode); - chqrlie
不,我建议手动使用ASCII字符“0”和条件语句来完成它。 - A P
@AviPars:抱歉,我误读了链接。对于两位数的数字,这种手动方法是可以的,但对于五位数的邮政编码,除非您可以假定邮政编码是一个有效的美国邮政编码(从01001开始),否则处理所有可能性需要更多的代码。 - chqrlie
1
@chqrlie,这就是为什么我没有将它提交作为答案的原因——但人们知道有不同的处理问题的方法都是有效的,这很好。 - A P
11个回答

686
printf("%05d", zipCode);

0 表示填充字符,5 表示整数数字的宽度。

示例 1:如果使用 "%02d"(用于日期),则只会在个位数前面填充零。例如,06 而不是 6

示例 2:"%03d" 会在个位数前填充 2 个零,在十位数前填充 1 个零。例如,数字 7 填充为 007,数字 17 填充为 017


282
请勿将邮政编码存储为数字。一些国家的邮政编码中包含字母。 - Sec
1
对于您的情况,这应该足够了。如何在长度未知的整数中有前导零? - Dominic Motuka
3
你需要知道最终填充字符串的最大长度。或者,如果你总是想要5个前导零,则可以使用"00000" + integer.to_s等方法。 - mlambie

176

正确的解决方案是将邮政编码存储为字符串(STRING)在数据库中。尽管它看起来像一个数字,但实际上它不是数字,而是一种代码,其中每个部分都有意义。

数字是进行算术运算的东西。邮政编码不是这样的。


34
是的,你的观察完全正确。那就是我的做法。然而,提问者可能正在处理作业,而不是生产代码。回答需要根据提问者的情况量身定制。 - EvilTeach
18
我想我应该更精确地表述,以说明我是想了解如何在一种我不熟悉的语言中添加前缀和后缀字符。将来我会更加小心使用任意例子! - zxcv
3
其他国家,如英国,在邮政编码中有字母。 - jjxtra

48

您可以在最小字段宽度前面加上零:

printf("%05d", zipcode);

17
sprintf(mystring, "%05d", myInt);

这里的"05"表示“使用5位带前导零的数字”。


16

如果您使用 *nix 系统:

man 3 printf

这将显示一个手册页面,类似于:

0 值应该用零进行填充。对于d、i、o、u、x、X、a、A、e、E、f、F、g和G的转换,转换后的值在左侧用零而不是空格进行填充。如果同时出现0标志和-标志,则忽略0标志。如果使用数字转换(d、i、o、u、x和X)给出了精度,则忽略0标志。对于其他转换,行为未定义。

尽管问题是关于C语言的,这个页面可能会有帮助。


1
为什么需要这个三个数字? - eri0o
4
如果你在man命令后面加上数字参数,它就会限定在特定的章节内搜索。如果不加,你将得到shell命令printf的帮助文档而非C函数的文档。请注意,本翻译尽量保留原意并简化语言,如有歧义或错误,请以原文为准。 - Paul Tomblin

16

邮政编码是一个高度本地化的领域,许多国家在其邮政编码中使用字符,例如英国、加拿大。因此,在任何时候如果您需要从其他国家发货或获取用户、客户、客户端等信息,您应该使用字符串/ varchar字段进行存储。

然而,在一般情况下,您应该使用推荐答案(printf("%05d", number);)。


13

有两种方法可以输出以前导零的数字:

使用0标记和宽度说明符:

int zipcode = 123;
printf("%05d\n", zipcode);  // Outputs 00123

使用精度说明符:

int zipcode = 123;
printf("%.5d\n", zipcode);  // Outputs 00123

这两者之间的区别在于负数的处理方式:
printf("%05d\n", -123);  // Outputs -0123 (pad to 5 characters)
printf("%.5d\n", -123);  // Outputs -00123 (pad to 5 digits)

邮政编码不太可能是负数,所以这并不重要。

但是请注意,邮政编码实际上可能包含字母和破折号,因此应该将它们存储为字符串。在字符串中包括前导零非常简单,因此可以更简单地解决您的问题。

请注意,在上面两个示例中,5的宽度或精度值可以指定为int参数:

int width = 5;
printf("%0*d\n", width, 123);  // Outputs 00123
printf("%.*d\n", width, 123);  // Outputs 00123

还有一个需要知道的技巧:当精度为0时,值为0时不会输出任何内容:

printf("|%0d|%0d|\n", 0, 1);   // Outputs |0|1|
printf("|%.0d|%.0d|\n", 0, 1); // Outputs ||1|

6

printf允许使用不同的格式选项。

例如:

printf("leading zeros %05d", 123);

2

如果你把ZIP码以字符形式存储,而不是数字形式,那么你将避免很多麻烦(长期来看)。因为ZIP码本质上是一个字符字符串,而不是一个数字。


如果有人能解释如何对 char 数组进行零填充就好了。甚至有一个解决方案使用 atoi() 将 char 数组转换为整数,然后使用 %05d 进行格式化输出。希望这不是唯一的解决方案。 - Niko
@Niko 嗯,我猜你可以使用 memcpy 等函数来将字符数组填充为零。但是你到底为什么要这样做呢? - Героям слава

0
如果您需要将邮政编码存储在字符数组zipcode[]中,可以使用以下代码:
snprintf(zipcode, 6, "%05.5d", atoi(zipcode));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接