问题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