现在的位置: 首页 > 综合 > 正文

%02hhX

2014年09月21日 ⁄ 综合 ⁄ 共 1749字 ⁄ 字号 评论关闭

问题1:每次看到人家的十六进制输出,对齐的很好,ff就显示了,而我的总是0xffffffff。
如果是
"%02x",是以0补齐2位数,如果超过2位就显示实际的数;
"%hhx" 是只输出2位数,即便超了,也只显示低两位;
 
因此有了"%02hhx"

点击(此处)折叠或打开
void hexdump(char *buf, int num)
{
. int i;

. for(i = 0; i < num; i++) {
. . printf("%02hhx\t", buf[i]);
. . if ((i+1)%8 == 0) {
. . . printf("\n");
. . }
. }
. printf("\n");
}
参考:http://blog.chinaunix.net/uid-20801390-id-3207987.html

问题2:关于字符(char)的问题:难道字符不是8位(8 bits)?

最近正好针对字符得编程做得多一些。发现了一个问题,在Visual C++和C++ Builder 平台都存在的问题。
编译环境:缺省设置。
根据MSDN的解释,在C++中,char 是一个字节(8bits),unsigned char 也是一个字节(8bits)。两者具有共同的数据范围:0x00到0xFF,如果用它们表示整数的话,范围分别就是-128到127,0到255;但用16进制表示都是一样的:即00到FF。

但是在输出时,发生了奇怪的现象:

代码:
......
char x = 0x80;
CString str;//CString 是MFC定义的字符串类。
str.Format("%X",x);
......
结果:
str显示为32bit的数:FFFFFF80,显然,与MSDN的描述矛盾了。MSDN说是8bits,结果却是32bits!!!
如果,给x赋的值小于等于0x7F,那么str的内容只有8bits,与MSDN的描述一致。
又如果把上面的变量x声明为unsigned char ,则不论给x赋何值,str的内容永远都是8bits,与MSDN的描述一致。

上面的问题在C++ Builder平台也是如此。

A1:32位系统上%x默认是按照32位数来处理的,也就是一般的int32,在计算机内部,负数是用补码表示的,char是有符号的数,但char的最高位为1时,是负数,转换为int32是也是负数,所以但char是0x80是,最高位为负数,转换为int32后为FFFFFF80,但unsigned char为非负数,不存在补码的表示,也转换为 unsigned int32,值为00000080,但%x默认不打起面的0的,所以为显示为0x80, 但char为0x7F是,最高位为0,是非负数,转换为int32后为0x0000007F,所以打印出也为0x7F

A2:str.Format("%X",x); 
format是不会检查type的。所以 %X就直接拿了在&x的32bit
正确写法是 str.Format("%02hhX",x); 
// ???   按照问题1的说法,这样不是直接截断了,即使真的是32bit的也会截断成8bit了,是吧?

A3:%x 是以十六进制输出无符号整型的;
所以 str.Format( "%x", x ) 会自动把x 转换成无符号整形的

例如测试如下:
   __int64 a = 0x0000ffffffffffff;
   str.Format( "%x", a );
   str = "ffffffff";

转换的规则是 不足32位的 高位是1  扩展位补1
                     高位是0  扩展位补0;

参考:http://bbs.csdn.net/topics/200084498

十六进制 字符 (以十六进制形式打印字符)
0 对于所有的数字格式,用前导零而不是用空格填充字段宽度

hh和整数转换符一起使用,表示一个char或者unsigned char类型数值
printf("%02hhx ", *(char *)v_addr);

h和整数转换符一起使用,表示一个short或者unsigned short类型数值
printf("%04hx ", *(short *)v_addr);

printf("%08x ", *(int *)v_addr);
参考:http://hi.baidu.com/zengzhaonong/item/ec7fc031e2f1cb21b2c0c582

抱歉!评论已关闭.