如何解决将原始ASCII数据转换为十六进制字符串
我有以下代码将原始ASCII数据转换为十六进制字符串。完整的c代码可以在here
中找到void str2hex(char* inputStr,char* outputStr)
{
int i;
int counter;
i=0;
counter=0;
while(inputStr[counter] != '\0')
{
sprintf((char*)(outputStr+i),"%02X",inputStr[counter]);
i+=2; counter+=1;
}
outputStr[i++] = '\0';
}
它对于大多数值都适用。但是,当我尝试使用echo作为stdin echo 11223344556677881122334455667788|xxd -r -p| ./CProgram --stdin
11223344556677881122334455667788
它返回以下输出
11223344556677FF11223344556677FF
可以看出,它返回88
而不是FF
。
如何调整此代码以获取88
而不是FF
。
解决方法
有多个问题都汇入您的问题中。
第一个问题是,如果char
是有符号或无符号整数类型,则由编译器定义。您的编译器似乎已经签名了char
类型。
第二个问题是,在当今的大多数系统上,带符号的整数使用two's complement表示,其中最高有效位表示符号。
第三个问题是printf
之类的vararg函数将执行其default argument promotion的参数。这意味着小于int
的类型将是promoted至int
。升级将保留转换后的整数的值,这意味着负值将被符号扩展。符号扩展意味着扩展该值时,最高有效位将一直复制到“顶部”。这意味着有符号的字节0xff
在提升为0xffffffff
时将扩展为int
。
现在,当您的代码尝试转换字节0x88
时,它将被视为负数-120
,而不是您期望的136
。
对此有两种可能的解决方案:
-
明确使用
unsigned char
作为输入字符串:void str2hex(const unsigned char* inputStr,char* outputStr);
-
使用
printf
格式的hh
前缀:sprintf((char*)(outputStr+i),"%02hhX",inputStr[counter]);
这告诉
sprintf
,该参数是一个字节,并且将掩盖(提升的)整数的高位。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。