0

scanf与以下格式说明符一起使用时,被扫描的输入是123456什么时候与它是什么时候有什么区别123

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

输出有什么区别?

4

5 回答 5

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 找到它

于 2011-01-24T15:40:49.103 回答
5

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

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

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

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

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

于 2011-01-24T15:41:58.043 回答
1

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

于 2011-01-24T15:34:46.260 回答
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'。

于 2011-01-24T15:51:26.317 回答
0

两者%-6d%0d都是无效的转换规范scanf,因此这些情况的行为将​​是未定义的。请参阅语言标准,§ 7.19.6.2,¶ 3。

于 2011-01-24T15:44:07.120 回答