如何打印 uint32_t 和 uint16_t 变量的值?

55
我正在尝试打印一个 `uint16_t` 和 `uint32_t` 的值,但输出结果不符合预期。
#include <stdio.h>
#include <netinet/in.h>

int main()
{
    uint32_t a = 12, a1;
    uint16_t b = 1, b1;
    a1 = htonl(a);
    printf("%d---------%d", a1);
    b1 = htons(b);
    printf("\n%d-----%d", b, b1);
    return 0;
}

我也使用过。
printf("%"PRIu32, a);

显示错误。

如何打印这些值,期望的输出是什么?


7
展示给我们(精确!)的错误信息会比仅仅说“显示错误”更有帮助。而不是只是“没有给出期望的输出”,请展示给我们实际的输出结果(并拼写单词“输出”,而不是写“o/p”)。 - Keith Thompson
1
printf("%d---------%d",a1); 产生未定义的行为,因为您在格式字符串中有两个 %d,但只传递了一个参数。 - Jerry Jeremiah
2
可能是uint8_t,uint16_t等的格式说明符?的重复问题。 - phuclv
2个回答

82
如果您想要使用intN_t类型及其相似类型的新格式说明符,则需要包含inttypes.h。只有在编译器符合C99标准的情况下,这才是正确的(即可移植的)方式。如果大小与您所想的不同,则不应该使用类似于%d%u的标准说明符。 stdint.h包含并扩展了许多其他内容,例如可以用于printf/ scanf调用族的宏。这在ISO C99标准的第7.8节中有所涵盖。
例如,以下程序:
#include <stdio.h>
#include <inttypes.h>
int main (void) {
    uint32_t a=1234;
    uint16_t b=5678;
    printf("%" PRIu32 "\n",a);
    printf("%" PRIu16 "\n",b);
    return 0;
}

输出:

1234
5678

20
<inttypes.h>中定义的宏是打印类型为uint32_tuint16_t等类型值的最正确方式,但这并不是唯一的方式。

个人认为那些宏很难记住,使用起来也很麻烦。(考虑到printf格式字符串的语法,这可能是不可避免的;我并不是在说我能想出更好的系统。)

另一种方法是将值强制转换为预定义类型,并使用该类型的格式。

intunsigned int类型被语言保证至少有16位宽度,因此能够容纳任何类型为int16_tuint16_t的转换值。同样,longunsigned long至少有32位宽度,而long longunsigned long long至少有64位宽度。

例如,我可能像这样编写您的程序(稍作调整):

#include <stdio.h>
#include <stdint.h>
#include <netinet/in.h>  

int main(void)
{
    uint32_t a=12, a1;
    uint16_t b=1, b1;
    a1 = htonl(a);
    printf("%lu---------%lu\n", (unsigned long)a, (unsigned long)a1);
    b1 = htons(b);
    printf("%u-----%u\n", (unsigned)b, (unsigned)b1);
    return 0;
}

这种方法的一个优点是它可以即使在不支持 <inttypes.h> 的 C99 之前的实现中使用。这样的实现很可能也不会有 <stdint.h>,但该技术对其他整数类型也很有用。


1
这里有一个非常小的边缘情况,如果有符号整数不是二进制补码。在这种情况下,它将无法正确地保存最负的二进制补码值。非常小的问题,我承认,但如果您想要最大的可移植性,需要注意。 - paxdiablo
1
@paxdiablo:intN_t类型要求是没有填充位的二进制补码。如果int不是二进制补码,则intN_t类型可能不会被定义,除非实现也支持不同的二进制补码类型。这是个好观点,但我认为它比你所暗示的边缘情况还要小。 - Keith Thompson
1
毫无疑问。我怀疑你会很难在地球上找到一台机器,它拥有新的整数类型,但仍然具有补码或符号/幅度int类型 :-) - paxdiablo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接