-6

在 C 语言中,下面的程序是 %5%% ,但我不知道怎么做?

 printf("%6%5%%%78%");
4

3 回答 3

6

这是未定义的行为,并且是编译器/平台特定的。带有错误参数的 Printf 函数将开始从堆栈中提取变量,然后任何事情都可能发生。

这就是为什么编译器通常会抱怨这个

source.c:5:5: warning: conversion lacks type at end of format [-Wformat]
source.c:5:5: warning: conversion lacks type at end of format [-Wformat]
source.c:5:5: warning: conversion lacks type at end of format [-Wformat]
source.c:5:5: warning: spurious trailing '%' in format [-Wformat]
于 2012-10-01T15:52:30.207 回答
3

Printf 格式字符串后面应该跟相等数量的参数,这里显然没有这样做。

printf 格式字符串的可能参数是:

%[flags][width][.precision][length]specifier

其中说明符是s代表stringc代表char等。其他是可选的。

标志是左对齐或右对齐的 +、-、0 等之一,这些标志都没有在问题中传递。

精度以 . 为前缀,因此在本示例中不存在。

让我们看看

printf("%6%5%%%78%");
  • 现在 % 之后的第一个参数被视为字段的宽度,即 6,因此不打印。但是,它需要一个说明符,而不是找到另一个 %。标准说 % 后跟 % 将其打印到标准输出。因此,您首先看到 % 打印。现在因为 % 的效果丢失了,所以 5 被当作正常数字处理和打印。

  • 然后我们看到 %% 会打印一个 %。接下来是单个 %,然后是 78,它应该是宽度,因此不会打印。但是,后一个 % 否定了 78 的效果并打印了一个 %。

为了验证上述评估,这里是一个测试字符串

printf("%6%4%3%2");

打印 %4%2 符合上述要求。

详细参考 printf

于 2012-10-01T16:24:03.280 回答
0

这里可能发生的是:

  • printf 实现看到“%6”,它可以是有效转换规范的开始,例如“%6d”。
  • 然后它看到“%”,这不再是一个有效的转换规范。此时字符串不符合 C 标准(例如,C 1999 7.19.6.1 8 表示“完整的转换规范应为 %%。”),实现可以做任何事情。这个特定的实现似乎忽略了“6”,并且好像转换规范是“%%”而不是“%6%”。因此,它将“%”写入标准输出。
  • 然后 printf 实现看到“5”,所以它写“5”。
  • 然后它看到“%%”,这是一个有效的转换规范,导致“%”被写入。
  • 然后它会看到“%78%”。与“%6%”一样,“%78”可以开始一个有效的规范,但第二个“%”是错误的。再一次,实现忽略“78”并写入“%”。

该行为在其他 C 实现中会有所不同。程序格式不正确;它不符合 C 标准,并且其行为未由 C 标准指定。

于 2012-10-01T17:00:35.503 回答