Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2358637
  • 博文数量: 527
  • 博客积分: 10343
  • 博客等级: 上将
  • 技术积分: 5565
  • 用 户 组: 普通用户
  • 注册时间: 2005-07-26 23:05
文章分类

全部博文(527)

文章存档

2014年(4)

2012年(13)

2011年(19)

2010年(91)

2009年(136)

2008年(142)

2007年(80)

2006年(29)

2005年(13)

我的朋友

分类: WINDOWS

2011-07-08 16:09:00

在printf中, %03d  格式中的0是有特殊含义的, 即输出不足3位宽时, 以0在左边补足.
而在scanf家族中, 这个0是没有相应含义的.

但在程序中表示整数时, 0123 又与123 有不同的语意, 前者标识了一个8进制数. 所以, scanf格式中使用%03d虽然在技术上不会错, 但却有其它方面的不完美.

把0写在这里的程序员, 很可能是期望能自动处理输入中的前导0.
还有一种可能是希望把带有前导0的数字当作8进制来parse.

这两种期望, 第一个会实现, 但冗余, %3d 与 %03d的效果一样, 数字中的前导0在计算宽度时, 同样算数的, 也就是对"01234",  只会解析"012"

这第二个, 则完全不可能.

所以, 即使 pc-lint 9.00g和 vc的PREFast(/analyze)都不会检查出来这种格式错误, 它仍然是一个潜在的问题, 程序员的心理预期与这段代码的实际行为之间可能存在念头.

之所以写了%03d 也没有暴露出来错误, 是因为比如VC运行时库的代码中, 把%之后的数字统一地看作是10进制的数进行解析来计算宽度. 在
C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\input.c
的Line 495(VS2010) 上下我找到了这段实现代码:
                if (_ISDIGIT((_TUCHAR)comchr)) {
                    ++widthset;
                    width = MUL10(width) + (comchr - _T('0'));
                } else
...
阅读(5018) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~