格式化IO函数(*printf / *scanf)中的转换说明符%i和%d有什么区别?

229
在printf和scanf中,%d和%i作为格式说明符时有什么区别?
4个回答

325

在输出时,例如使用printf,它们是相同的。

然而,在作为输入指示符时,例如使用scanf,它们是不同的。其中,%d将带符号的十进制数作为整数进行扫描,但%i默认为十进制,同时允许以十六进制(如果前缀为0x)和八进制(如果前缀为0)表示。

因此,对于033,使用%i将得到27,但使用%d将得到33。


12
在 sscanf 函数中,期望一个可能包含前导零的整数对我来说似乎是最合理的默认行为。如果你不期望八进制,那么这可能会导致微妙的错误。因此,这表明当你需要任意选择一个格式说明符时,%d 是一个很好的选择,除非你明确想要读取八进制和/或十六进制。 - Eliot
2
啊!这很有道理!现在我知道该看什么了,这也可以在 printfscanf 的文档中看到。 - Gabriel Staples
八进制在Javascript中曾经让我吃过亏(数据库中的某些数字值最初以字符串形式出现,带有前导零)。这真是一个难缠的错误。 - Scott Smith

75

对于printf%d%i都表示有符号十进制整数。但是对于scanf%d%i同样表示有符号整数,但是如果%i前面有0x,则将其解释为十六进制数;如果前面有0,则将其解释为八进制数;如果没有前缀,则将其解释为十进制数。


24
%i%d对于printf格式说明符来说没有区别。我们可以通过查看C99标准草案7.19.6.1The fprintf function来了解这一点,该节还涵盖了有关格式说明符的printf,其中第8段落写道:

转换说明符及其含义如下:

并包括以下内容:

d,i     The int argument is converted to signed decimal in the style
        [−]dddd. The precision specifies the minimum number of digits to
        appear; if the value being converted can be represented in fewer
        digits, it is expanded with leading zeros. The default precision is
        1. The result of converting a zero value with a precision of zero is
        no characters.
另一方面,对于scanf而言,有所不同,%d会假设为十进制,而%i则会自动检测进制。我们可以在第7.19.6.2节中查看相关内容,该部分包含了关于格式说明符的scanf的信息,在第12段落中指出:

转换说明符及其含义如下:

具体内容如下:

d     Matches an optionally signed decimal integer, whose format is the
      same as expected for the subject sequence of the strtol function with
      the value 10 for the base argument. The corresponding argument shall
      be a pointer to signed integer.

i     Matches an optionally signed integer, whose format is the same as
      expected for the subject sequence of the strtol function with the
      value 0 for the base argument. The corresponding argument shall be a
      pointer to signed integer.

3

printf中没有任何区别,这两个词是同义词。


11
正如被接受的答案所说,在 scanf() 格式字符串中使用时会有所不同。 - J...S

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