在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) |