【问题标题】:Using printf width specifier with fixed width integer type variable使用具有固定宽度整数类型变量的 printf 宽度说明符
【发布时间】:2020-02-05 19:12:54
【问题描述】:

w是指定输出宽度的参数,p是数字,应该以八进制打印 这两个变量都应该是固定宽度的整数(uint32_t)(这是我的编程课的任务)。 我用谷歌搜索,我可以使用宏 PRIo32 (inttypes.h) 以八进制打印 int32_t,但我找不到任何宽度说明符的宏。 所以当我尝试时:

printf("%*" PRIo32 "\n", w, p);

我在测试系统中收到此错误

错误:字段宽度说明符“*”需要“int”类型的参数,但参数 2 的类型为“int32_t”[-Werror=format=]

有没有解决这个问题的宏?还是我应该试试别的?

【问题讨论】:

  • 我认为这很清楚。 * 期望 int,但 wint32_t。您应该提供int 参数。您可以将w 转换为int
  • 但我必须使用int32_t。该任务明确表示禁止假设 int 为 4 个字节,使用 int 的解决方案被简单地拒绝
  • 那么它就自相矛盾了。您必须将 int 传递给 printf 以指定宽度说明符。
  • * 修饰符总是需要int 类型。总是。所以如果你有w,你知道它是int32_t,并且你把它转换成(int),你就不会在你的机器上假设int的大小。你假设你机器上int 的大小与你机器上int 的大小相同,这与你使用* 修饰符时printf 所做的假设完全相同,所以你'重金。 (如果int 在您的机器上小于 小于int32_t,并且如果w 大于32767,那么您就有问题了,但是没有人打印那么宽的字段,所以您应该没问题。 )

标签: c printf posix int32


【解决方案1】:

uint32_t 宽度转换为int@Kamil Cuk

// printf("%*" PRIo32 "\n", w, p);
printf("%*" PRIo32 "\n", (int) w, p);

如有必要,检测极端情况

assert(w <= INT_MAX);
printf("%*" PRIo32 "\n", (int) w, p);

不需要关于int 范围的假设。


更深入

请注意,由于环境限制,具有 巨大 宽度的单个打印件会遇到问题。超过 4095 左右的宽度可能根本不起作用。

环境限制 任何一次转换可以产生的字符数至少为 4095. C17dr § 7.21.6.1 15

代码可以使用下面的代码来处理病态的大宽度 - 尽管效率不高。

uint32_t w2 = w;
while (w2 > 100) {
  w2--;
  putchar(' ');
}
printf("%*" PRIo32 "\n", (int) w2, p);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-22
    • 1970-01-01
    • 2013-05-26
    相关资源
    最近更新 更多