Scanf 语法 - %6d 和 %-6d 和 %0d
-
24-10-2019 - |
题
使用上有什么区别 scanf
使用以下格式说明符,当正在扫描的输入是 123456
与当它是 123
:
%6d
%-6d
%0d
输出有什么区别?
解决方案
我最终只是用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)找到了它)
其他提示
这 %-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
需要一个 非零小数整数 作为最大场宽度,它必须是一个无标记的整数。
我认为这将发生:%6D将为您提供数字的前6位数字,%-6D可能无法正常工作,因为 - 更多是输出对齐式规范符。 %0D意味着您只需0个字符,这可能无法按预期工作。
两个都 %-6d
和 %0d
是 无效的 转换规范 scanf
, ,所以这些情况下的行为将是 不明确的. 。查看语言 标准, § 7.19.6.2, ¶ 3.
我假设像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”。