无符号短整型的格式说明符是什么?

163
我有以下的程序。
#include <stdio.h>

int main(void)
{
    unsigned short int length = 10; 

    printf("Enter length : ");
    scanf("%u", &length);

    printf("value is %u \n", length);

    return 0;
}

当使用gcc filename.c编译时,出现了以下警告(在scanf()行)。 warning: format ‘%u’ expects argument of type ‘unsigned int *’, but argument 2 has type ‘short unsigned int *’ [-Wformat] 然后我参考了C99 specification - 7.19.6 Formatted input/output functions,但是无法理解在使用长度修饰符(如shortlong等)与unsigned一起使用时的正确格式说明符。 %u是正确的说明符吗?如果是,为什么会出现上述警告?
编辑: 大部分时间,我尝试使用%uh,但仍然出现警告。

3
printf("%u\n", (unsigned int)length); // 总是有效的,因为您所读的C99规范保证了 sizeof(short) <= sizeof(int)(但下面的实际答案当然更好)。 - Philip
1
不需要进行强制类型转换;默认的提升会处理它。 - R.. GitHub STOP HELPING ICE
你应该使用%hu而不是%uh - undefined
5个回答

197

尝试使用"%h"修饰符:

scanf("%hu", &length);
        ^

ISO/IEC 9899:201x - 7.21.6.1-7

规定以下的 d、i、o、u、x、X 或 n 转换说明符适用于类型为指向 short 或 unsigned short 的指针的参数。


63
对于 scanf,您需要使用 %hu,因为您传递了一个指向 unsigned short 的指针。对于 printf,由于默认提升,无法传递 unsigned short(它将被提升为 intunsigned int,具体取决于 int 是否具有与 unsigned short 至少相同数量的值位数),因此 %d%u 都可以。当然,如果您愿意,也可以自由使用 %hu

12

来自Linux手册页:

h      以下整数转换对应于short int或unsigned short int参数,或以下n转换对应于指向short int参数的指针。

因此,要打印无符号短整数,格式字符串应为"%hu"


1
我认为这不是正确的打印short int的方式,因为它们会自动提升为int(就像char一样)。 - Alexey Frunze
3
@Alex,在printf函数中,%hu/%hd可以正常使用。只有在C99版本中才能使用%hhu/%hhd。%h和%hh会将传递的整数与0xFFFF或0xFF进行按位与运算。 - jørgensen

9
这是一个关于printf格式说明符的好表格。对于unsigned short int,应该使用%hu
还有一篇关于C数据类型的维基百科链接

0
对于 `printf`,由于默认提升(unsigned short 将会转换为 int 或 unsigned int,具体取决于 int 是否具有与 unsigned short 相同的值位数),所以使用 `%d` 或 `%u` 即可。
但仍然可以手动将这个 short int 的值转换为由 '0' 和 '1' 组成的 char 数组,然后使用另一个循环创建一个 short int 值并打印它。
我们这样做:
struct byte3data {
    char a;
    char b;
    char c;
};
void my_printf(byte3data myOwnType) {
    // Writing 3 bytes with printf() in the way we want
}

printf只是基本工具,我认为应该这样对待它。您可以以任何方式管理位。而且,使用浮点算术,您不仅可以回答“是”或“否”,还可以回答“多少”。尝试在句子中将printf更改为printfs,然后再考虑一下。


这并没有回答问题。一旦您拥有足够的声望,您将能够评论任何帖子;相反,提供不需要询问者澄清的答案。- 来自审核 - user16217248
好的好的好的,不要生气,我正在更正我的答案。 - user15624022
我并不生气,只是有些难以理解你的回答如何解决问题。你是在建议创建自己的 printf() 版本吗? - user16217248
1
是的和不是的,我的意思是“printf”可以是“printfs” - 您可以使用它们来编写任何数据,或者使用char数据类型 - 或者(如果您需要比8位更小的位表示 - 在不同的区域上操作)。当我正在制作将任何数据类型转换为任何数据类型的应用程序时,我写下了我的第一个答案,因此从实际角度深入研究了这个主题。 - user15624022

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