scanf
与以下格式说明符一起使用时,被扫描的输入是123456
什么时候与它是什么时候有什么区别123
:
%6d
%-6d
%0d
输出有什么区别?
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
作为整数时,它实际上是一元-
和+
运算符词位,后跟十进制整数词位。因此,由于规范scanf
要求一个非零十进制整数作为最大字段宽度,它必须是一个无符号整数。
这就是我认为会发生的事情: %6d 会得到数字的前 6 位数字, %-6d 可能不会像你期望的那样工作,因为 - 更多的是输出对齐说明符。%0d 意味着您只需要 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'。
两者%-6d
和%0d
都是无效的转换规范scanf
,因此这些情况的行为将是未定义的。请参阅语言标准,§ 7.19.6.2,¶ 3。