【问题标题】:printf format specifiers for uint32_t and size_tuint32_t 和 size_t 的 printf 格式说明符
【发布时间】:2011-03-11 05:50:10
【问题描述】:

我有以下

size_t   i = 0;
uint32_t k = 0;

printf("i [ %lu ] k [ %u ]\n", i, k);

编译时收到以下警告:

format ‘%lu’ expects type ‘long unsigned int’, but argument has type ‘uint32_t’

当我使用夹板运行此程序时,我得到以下信息:

Format argument 1 to printf (%u) expects unsigned int gets size_t: k

非常感谢您的建议,

【问题讨论】:

  • C89 不支持来自<stdint.h><inttypes.h>uint32_t;如果你想使用这些类型,你应该升级到 C89。作为扩展,GCC 可能确实允许您使用它们,但 C89 没有任何此类支持。
  • size_t 的官方 C99 格式修饰符是“z”,如 "%zu"
  • 我相信@kenny 的答案最适合uint32_t,但它缺少size_t。 @u0b34a0f6ae 的答案包括两者。
  • Jonathan Leffler 在第一条评论中第二次提到 C89 应该是 C99

标签: c printf


【解决方案1】:

How do I print uint32_t and uint16_t variables' value?

#include <stdio.h>     // need at least one of these two
#include <inttypes.h>
int main (void) {
    uint32_t a=1234;
    uint16_t b=5678;
    printf("%" PRIu32 "\n",a);
    printf("%" PRIu16 "\n",b);
    return 0;
}

【讨论】:

  • 链接的问题谈到uint32_t,但是size_t呢?
【解决方案2】:

听起来您希望size_tunsigned long(可能是64 位)相同,而实际上它是unsigned int(32 位)。在这两种情况下都尝试使用%zu

但我并不完全确定。

【讨论】:

  • 编译时没有警告。但是,运行夹板我得到以下信息:1)printf(%u)期望 unsigned int 得到 uint32_t:i 2)printf(%u)期望 unsigned int 得到 size_t:k
  • 听起来夹板只是迂腐,那么。它可能与源代码中的类型名称不同,并且没有意识到它们是等价的。我想知道@KennyTM 的回答会做什么......它当然应该更便携。
  • 夹板实际上是在做正确的事情。仅仅因为 int32_t 在您的编译器/平台上恰好是 int 并不意味着它可能不在另一个 long 上。 size_t 也一样。它实际上正在竭尽全力并做更多工作来检测这个可移植性错误,因为简单、自然的检查就是像编译器一样尊重 typedef。
  • -1,抱歉它不便携。所需要的只是格式说明符和类型一致,并且您始终可以强制转换以实现这一点。 long 至少是 32 位,所以 %lu(unsigned long)k 总是正确的。 size_t 比较棘手,这就是为什么在 C99 中添加了 %zu。如果你不能使用它,那么就像k一样对待它(long是C89中最大的类型,size_t不太可能更大)。
【解决方案3】:

所需要的只是格式说明符和类型一致,并且您始终可以强制转换以实现这一点。 long 至少是 32 位,所以 %lu(unsigned long)k 总是正确的:

uint32_t k;
printf("%lu\n", (unsigned long)k);

size_t 比较棘手,这就是为什么在 C99 中添加了%zu。如果你不能使用它,那么就像k一样对待它(long是C89中最大的类型,size_t不太可能更大)。

size_t sz;
printf("%zu\n", sz);  /* C99 version */
printf("%lu\n", (unsigned long)sz);  /* common C89 version */

如果你没有得到正确的格式说明符,那么printf 将相当于从数组中读取太多或太少的内存。只要您使用显式类型转换来匹配类型,它就可以移植。

【讨论】:

    【解决方案4】:

    如果您不想使用 PRI* 宏,另一种打印 ANY 整数类型的方法是强制转换为 intmax_tuintmax_t 并使用 "%jd"%ju , 分别。这对于没有定义 PRI* 宏的 POSIX(或其他操作系统)类型特别有用,例如 off_t

    【讨论】:

      【解决方案5】:

      试试

      #include <inttypes.h>
      ...
      
      printf("i [ %zu ] k [ %"PRIu32" ]\n", i, k);
      

      z 表示长度与size_t 相同的整数,PRIu32defined in the C99 header inttypes.h 表示无符号 32 位整数。

      【讨论】:

      • @robUK:呵呵。我建议你提交一个关于夹板的错误。
      • 这是正确的答案。虽然我个人的建议是简单地投射,例如printf( "%lu", (unsigned long )i )。否则,由于类型更改,稍后会在整个代码中出现一堆警告。
      • 这是正确答案。我同意 KennyTM 关于提交夹板错误的意见。顺便说一句,“%zu”是 size_t 的正确格式。您不需要任何 PRI* 宏来打印 size_t。
      • 如果我没记错的话 %zu 是 C99,在问题中他写了 'C89'。
      • @alcor 是的,他确实放了 C89(显然是他正在使用的 gcc 编译器标志),但他使用的是 uint32_t 所以实际上它是 C99 代码,应该这样编译。
      猜你喜欢
      • 2013-03-14
      • 2012-05-17
      • 2012-05-17
      • 1970-01-01
      • 1970-01-01
      • 2017-11-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多