我可以指定数字,例如printf("%08x", ...)
。但我想根据数据类型自动调整位数(例如long
(64位)应自动具有64/4 = 16位数字)。有办法吗?谢谢。
答案 0 :(得分:4)
如何
printf(“%0x”)
使用根据类型确定的位数?
1)找到位宽
使用sizeof, CHAR_BIT
查找位宽度sizeof(x)*CHAR_BIT
1 或参见以下替代方法。
2)找到半字节宽度
(bit_width + 3)/4
表示半字节宽度-十六进制字符数。
3)通过宽度
使用"*"
传递 width 并使用最宽的类型uintmax_t
打印。
#include <float.h>
#include <limits.h>
#include <stdio.h>
#define PRINTF_XW(x) printf("%0*jx\n", (int)(sizeof(x)*CHAR_BIT+3)/4, (uintmax_t) (x))
int main(void) {
unsigned char uc = 1;
unsigned short us = 2;
unsigned u = 3;
unsigned long ul = 4;
unsigned long long ull = 5;
uintmax_t uj = 6;
PRINTF_XW(uc);
PRINTF_XW(us);
PRINTF_XW(u);
PRINTF_XW(ul);
PRINTF_XW(ull);
PRINTF_XW(uj);
return 0;
}
示例输出在不同平台之间可能会有所不同。
01
0002
00000003
0000000000000004
0000000000000005
0000000000000006
替代
另一种方法将使用_Generic
-需要更多的工作-可获得更多的回报。
请参见下面的unsigned long long uf:42;
示例。
#include <float.h>
#include <limits.h>
#include <stdint.h>
int hexwidth(uintmax_t u) {
int count = 3;
while (u) {
u >>= 1;
count++;
}
return count/4;
}
// Default case useful for other unsigned types wider than `unsigned`
#define HEXWIDTH(s) _Generic((s), \
unsigned char: hexwidth(UCHAR_MAX), \
unsigned short: hexwidth(USHRT_MAX), \
unsigned : hexwidth(UINT_MAX), \
unsigned long: hexwidth(ULONG_MAX), \
unsigned long long: hexwidth(ULLONG_MAX), \
default: hexwidth((s)*0u - 1u) \
)
#define PRINTF_XW(x) printf("%0*jx\n", HEXWIDTH(x), (uintmax_t) (x))
语言扩展名允许的字段超过unsigned
,效果也很好。
int main(void) {
struct {
unsigned long long uf:42;
} s1 = {7};
struct {
unsigned long long uf:51;
} s2 = {8};
PRINTF_XW(s1.uf);
PRINTF_XW(s2.uf);
}
输出
00000000007 <-- 11 digits
0000000000008 <-- 13 digits
Macro-magic可以用编译时间计算替换hexwidth(uintmax_t u)
如下:
#define NW3(x) (((x) > 0xFu) ? 2 : 1)
#define NW4(x) (((x) > 0xFFu) ? NW3((x)>>8)+2 : NW3(x))
#define NW5(x) (((x) > 0xFFFFu) ? NW4((x)>>16)+4 : NW4(x))
#define NW6(x) (((x) > 0xFFFFFFFFu) ? NW5((x)>>32)+8 : NW5(x))
#define NW(x) (((x) > 0xFFFFFFFFFFFFFFFFu) ? NW6((((x)+0llu)>>32)>>32)+16 : NW6((x)+0llu))
// Default case useful for all unsigned types as wide/wider than `unsigned`
#define HEXWIDTH(s) _Generic((s), \
unsigned char: NW(UCHAR_MAX), \
unsigned short: NW(USHRT_MAX), \
default: NW((s)*0u - 1u) \
)
1 当类型中没有填充时(在标准 unsigned 整数类型中常见)填充,此方法效果很好。
答案 1 :(得分:0)
您可能应该研究C的
#include <inttypes.h>
unit8_t value = 0x34;
printf("The value formatted for 8 bits is %" PRIx8 ".", value);
请注意,PRIx8
是一个字符串,正确地将其格式设置为“ printf”,“十六进制”,“八位”。
请注意,字符串之间没有逗号不是错误。这是一种格式化技术,使用了C中称为“自动字符串连接”的功能,因此三个字符串将被拍打在一起。 PRIx8
只是一种方便,这意味着对8位十六进制值进行正确的格式化。
要获得格式为32位的类似输出,可以使用PRIx32
。
有关inttypes.h
输出格式的简要概述,可以查看Good introduction to <inttypes.h>