我正在尝试读取一行字符,然后打印出字符的十六进制等效值.
例如,如果我有一个字符串,"0xc0 0xc0 abc123"前两个字符是c0十六进制,其余字符是abc123ASCII,那么我应该得到
c0 c0 61 62 63 31 32 33
Run Code Online (Sandbox Code Playgroud)
但是,printf使用%x给了我
ffffffc0 ffffffc0 61 62 63 31 32 33
Run Code Online (Sandbox Code Playgroud)
如何在不使用的情况下获得我想要的输出"ffffff"?为什么只有c0(和80)有ffffff,但没有其他字符?
Mys*_*ial 115
您看到ffffff因为char您的系统已签名.在C语言中,可变参数的功能,比如printf将促进所有整数小于int到int.由于char是一个整数(在您的情况下为8位有符号整数),因此您的字符将int通过符号扩展名提升.
由于c0并且80具有前导1位(并且是8位整数的负数),所以它们是符号扩展的,而样本中的其他符号则不是.
char int
c0 -> ffffffc0
80 -> ffffff80
61 -> 00000061
Run Code Online (Sandbox Code Playgroud)
这是一个解决方案:
char ch = 0xC0;
printf("%x", ch & 0xff);
Run Code Online (Sandbox Code Playgroud)
这将屏蔽高位并仅保留您想要的低8位.
小智 57
实际上,有类型转换为int.您还可以使用%hhx说明符强制类型为char.
printf("%hhX", a);
Run Code Online (Sandbox Code Playgroud)
在大多数情况下,您还需要设置最小长度以使用零填充第二个字符:
printf("%02hhX", a);
Run Code Online (Sandbox Code Playgroud)
ISO/IEC 9899:201x说:
7长度修饰符及其含义为:hh指定以下d,i,o,u,x或X转换说明符适用于signed char或unsigned char参数(该参数将根据整数提升进行提升,但在打印前,其值应转换为有符号字符或未签名字符); 或者说是以下
Hic*_*ham 27
您可以创建一个unsigned char:
unsigned char c = 0xc5;
Run Code Online (Sandbox Code Playgroud)
打印它会给予C5而不是ffffffc5.
只打印大于127的字符,ffffff因为它们是负数(字符是有符号的).
或者你可以施放char同时打印:
char c = 0xc5;
printf("%x", (unsigned char)c);
Run Code Online (Sandbox Code Playgroud)
Tim*_*mmm 12
您可以hh用来告诉printf参数是unsigned char.使用0以获得零填充和2所述宽度设置为2 x或X更低/大写十六进制字符.
uint8_t a = 0x0a;
printf("%02hhX", a); // Prints "0A"
printf("0x%02hhx", a); // Prints "0x0a"
Run Code Online (Sandbox Code Playgroud)
编辑:如果读者担心2501断言这不是'正确的'格式说明符,我建议他们再次阅读printf链接.特别:
即使%c需要int参数,由于调用可变参数函数时发生的整数提升,传递char也是安全的.
固定宽度字符类型(int8_t等)的正确转换规范在标题
<cinttypes>(C++)或<inttypes.h>(C)中定义(尽管PRIdMAX,PRIuMAX等与%jd,%ju等同义).
至于他关于signed vs unsigned的观点,在这种情况下它并不重要,因为值必须始终是正数并且很容易适合有符号的int.无论如何,没有签名的hexyximal格式说明符.
编辑2 :("何时承认 - 你错了"版本):
如果您在第311页(PDF的第329页)上阅读了实际的C11标准,您会发现:
HH:指定一以下
d,i,o,u,x,或X转换说明适用于一个signed char或unsigned char参数(该参数将被提升根据整数促销,但它的值应被转换成signed char或unsigned char之前印刷); 或者以下n转换说明符适用于指向signed char参数的指针.
lve*_*lla 11
您可能将值0xc0存储在char变量中,可能是有符号类型,并且您的值为负(最高位设置).然后,当打印时,它被转换为int,并且为了保持语义等价,编译器用0xff填充额外的字节,因此负数int将具有与负数相同的数值char.要解决此问题,请unsigned char在打印时强制转换为:
printf("%x", (unsigned char)variable);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
308165 次 |
| 最近记录: |