Scanf语法 - %6d和%-6d以及%0d

时间:2011-01-24 15:28:17

标签: c scanf format-specifiers

当正在扫描的输入为scanf123456时,使用123与以下格式说明符之间有何区别:

  • %6d
  • %-6d
  • %0d

输出有什么不同?

5 个答案:

答案 0 :(得分:5)

我最终只是尝试使用GCC 4.3.4,并获得以下内容:

  • %6d:工作正常;只读取6个字符(因此,如果您尝试阅读123456789,则只能阅读123456
  • %-6d:发出警告:

    warning: unknown conversion type character '-' in format
    

    不读取任何内容,并且正在写入的int未经修改

  • %0d:发出警告:

    warning: zero width in scanf format
    

    读取好像格式说明符中没有宽度(%d

我没有检查规格,看看这些结果是否有规定,或者GCC是如何处理的(编辑AndreyT found it

答案 1 :(得分:5)

%-6d是无效的格式说明符。 -中没有scanf的格式说明符。

%6d中,6部分称为最大字段宽度。它适用于所有格式说明符(不仅适用于d),并指定在执行任何特定于格式的转换之前要读取的最大字符数。例如,如果输入序列为1234567,则%3d将读取并转换123,而%6d将读取并转换123456

%0d是无效的格式说明符。 scanf中的最大字段宽度必须是非零整数(请参阅语言规范中的7.19.6.2/3)。

因此,我们将%6d作为您提供的三个中唯一有意义的格式说明符。在这种情况下,关于产出差异的问题(在结果中?)没有多大意义。

编辑:有人可能会争辩说,%-6d -6部分是最大字段宽度,满足非零小数的标准要求整数。但是,在C语言术语中,十进制整数作为词汇元素只是一个数字和数字序列。不允许包含标志。即-6+6都不是十进制整数。每次在程序中使用-6+6作为整数时,实际上是一元-+运算符lexeme后跟十进制整数lexeme。因此,由于scanf的规范要求非零十进制整数作为最大字段宽度,因此它必须是无符号整数。

答案 2 :(得分:1)

以下是我认为会发生的事情:%6d会得到数字的前6位,%-6d可能无法正常工作,因为 - 更多的是输出对齐说明符。 %0d意味着您只需要0个字符,这可能无法按预期工作。

答案 3 :(得分:0)

%-6d%0d都是<{1}}的无效转换规范,因此这些情况的行为将​​是未定义。请参阅语言standard,§7.19.6.2,¶3。

答案 4 :(得分:0)

我会像Arkadiy一样假设你真的是指printf风格的格式,因为你引用了“输出”。我还假设您正在使用C(正如标签所示)。

如果你跑:

printf("%6d %-6d %0d", num1, num2);

...你最终会遇到编译器错误(或者更糟糕的是,运行时错误),因为你没有为三种格式提供足够的参数。

我觉得那不是你要问的那个。我们假设您实际运行:

// (I've added some extra stuff to show how the formatting works.)
printf("'%6d'/'%-6d'/'%0d'", num2, num2, num2);

......你会得到:

'   123'/'123   '/'123'

通常情况下,如果字段宽度(在这种情况下为6)足够宽,则数字是右对齐的,空格填充。如果在字段宽度之前加上“ - ”,它们将是右对齐的,空格填充。

这里的细微之处在于“%0d”格式。您可能认为您正在指定一个零宽度字段......而且您错了。 '%'后面的第一件事是选项标志,'0'是有效标志。这意味着,“如果字段宽度比内容宽,则左边有零填充。”在这种情况下,你没有提供字段宽度(“0”是一个标志,还记得吗?),因此“0”标志无效:该字段将与内容所需的一样宽。

但是,有一个更糟糕的微妙之处。如果你指定了“%-06d”,你会用零填充右边,对吗?不。 ' - '标志覆盖'0'标志,无论它们提供哪种顺序。你会得到'123'。