【问题标题】:Convert raw ASCII data to Hex string将原始 ASCII 数据转换为十六进制字符串
【发布时间】:2020-10-15 10:43:04
【问题描述】:

我有以下代码将原始 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 as stdin echo 11223344556677881122334455667788|xxd -r -p| ./CProgram --stdin从终端尝试以下输入时@

11223344556677881122334455667788

它返回以下输出

11223344556677FF11223344556677FF

可以看出,它返回的是FF,而不是88

如何调整此代码以获取 88 而不是 FF

【问题讨论】:

  • 请提供minimal verifiable example。此外,不清楚您为什么说"11223344556677881122334455667788" 的输入应该返回完全相同的字符串。这就是你说的吗?如果不是,请澄清。
  • But when I am trying the following input“你如何”尝试以下输入?请将代码和您的修改以文本形式发布到问题中。不需要outputStr[i++] = '\0'; - sprintf 已经这样做了。
  • 我用尝试将输入传递给程序的方式更新了问题
  • 在看到你如何输入之后,我更新了我的答案。问题本质上是符号问题(inputStr[counter] 可能是一个数)。

标签: c hex


【解决方案1】:

有多个问题都合并到您的问题中。

第一个问题是如果char 是有符号或无符号整数类型,它是编译器定义的。您的编译器似乎已签署 char 类型。

第二个问题是,在当今的大多数系统上,有符号整数使用two's complement 表示,其中最高有效位表示符号。

第三个问题是像printf 这样的可变参数函数将对其参数执行default argument promotion。这意味着小于int 的类型将是promotedint。并且该提升将保留转换后的整数的值,这意味着负值将被符号扩展。符号扩展意味着在扩展值时最高有效位将一直复制到“顶部”。这意味着当提升为int 时,有符号字节0xff 将扩展为0xffffffff

现在,当您的代码尝试转换字节 0x88 时,它将被视为负数 -120,而不是您所期望的 136

对此有两种可能的解决方案:

  1. 明确使用unsigned char 作为输入字符串:

    void str2hex(const unsigned char* inputStr, char* outputStr);
    
  2. printf 格式中使用hh 前缀:

    sprintf((char*)(outputStr+i),"%02hhX", inputStr[counter]);
    

    这告诉sprintf参数是一个单字节,并且会屏蔽掉(提升的)整数的高位。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-24
    • 2011-11-21
    • 2015-05-22
    • 2011-10-26
    • 2016-07-24
    • 2017-09-28
    • 2014-11-16
    • 2013-06-17
    相关资源
    最近更新 更多