Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
十六进制到Ascii转换_C_Hex_Ascii - Fatal编程技术网

十六进制到Ascii转换

十六进制到Ascii转换,c,hex,ascii,C,Hex,Ascii,我的挑战是将十六进制值转换为ascii,输入是一个指向uint8的指针,因此我需要逐字节转换,还有一个大小输入(没有字节),输入都是十六进制值,请帮助我找出代码中的错误 输出始终为0 uint8 ReferenceNumber[8] = {0x30,0x40,0x60,0x50,0x80,0x60,0x75,0x95}; HexToAscii(&ReferenceNumber[0], output, 8); static void HexToAscii(uint8* input, u

我的挑战是将十六进制值转换为ascii,输入是一个指向uint8的指针,因此我需要逐字节转换,还有一个大小输入(没有字节),输入都是十六进制值,请帮助我找出代码中的错误

输出始终为0

uint8 ReferenceNumber[8] = {0x30,0x40,0x60,0x50,0x80,0x60,0x75,0x95};
HexToAscii(&ReferenceNumber[0], output, 8); 

static void HexToAscii(uint8* input, uint8 *output, uint8 size)//No of bytes
{
    uint8 i, temp;

    for(i=1; i<=size; i++)
    {
        temp = (*(input)) >> (4*(i-1));
        temp &= 0x0F;
        temp +='0';
        if (temp >= (10+'0'))
        {
            temp += ('A'-10-'0');
        }
        *(output+size-i) = temp;
    }
}
uint8参考编号[8]={0x30,0x40,0x60,0x50,0x80,0x60,0x75,0x95};
HexToAscii(&ReferenceNumber[0],输出,8);
静态void HexToAscii(uint8*输入,uint8*输出,uint8大小)//字节数
{
uint8i,温度;
对于(i=1;i>(4*(i-1));
温度&=0x0F;
温度+='0';
如果(温度>=(10+'0'))
{
温度+=('A'-10-'0');
}
*(输出+尺寸i)=温度;
}
}
声明

temp = (*(input)) >> (4*(i-1));
可以改写为

uint8 x = *(input);
temp = x >> (4 * (i - 1));

现在您可以看到,实际上您正在将0、4、8、12等位的相同值向右移动。当将值向右移动时,您从左侧填充0,因此在循环的两次迭代后,
temp
变量始终为0

E1>>E2的结果是E1右移E2位。如果E1具有无符号类型或E1具有有符号类型和非负值,则结果的值是E1/2^E2商的整数部分1具有有符号类型和负值,结果值由实现定义。-

您需要增加
输入
指针。但是,在代码中,您需要为每个字节重复两次代码,即
uint8
的上下4位

我将这样做(将宏替换为内联函数,正如Olaf在中指出的那样):

/*!\brief将半字节(低4位)转换为十六进制值,以避免使用标准库。
*/
静态内联\uuuu属性\uuuu((始终\u内联,常量))字符
NibbleToHex(uint8\u t nibble){
返回((半字节>4u);
*(输出++)=NibbleToHex((*输入)和0x0Fu);
输入+++;/*<移动到下一个字节*/
}
}
uint8\u t ReferenceNumber[8]={0x30、0x40、0x60、0x50、0x80、0x60、0x75、0x95};
HexToAscii(ReferenceNumber,output,sizeof(ReferenceNumber)/sizeof(ReferenceNumber[0]);

注意
输出
必须始终是输入数据大小的两倍(假设
大小
变量等于输入数据的长度).

输入、实际结果和预期结果是什么?通过调试代码,您发现了什么?是否希望从十六进制转换为字符?以及预期的输出是什么?提示:“0123456789ABCDEF”*(输出+大小-i)=temp;你为什么要交换两端?太好了,我没想到会这样!我仍然想知道为什么我问这个问题得到了-1,输入[0]与输入不一样?。可能这就是我理解错误的地方!我不知道你为什么得到了-1。在你的例子中,
input
是内存中某个
uint8
类型变量上的指针。你通过用
*input
解除对指针的引用,得到该地址上的实际值,它等于
Input[0]
。因为您知道此指针指向多个连续值(数组),所以可以访问以下地址。
*input==input[0]
*(input+1)==input[1]
*(input+123)==input[123]
,…我使用手动递增指针而不是索引来消除对额外计数器变量的需要。是的,我知道*input与input[0]相同,但我认为input和&input[0]应该是一样的,我在我的第一条评论中漏掉了&你是对的-在本例中,与大多数情况一样,
input
&input[0]是相同的,我更喜欢<代码>输入<代码>,因为它不太打字/更清楚。但是,当使用<代码> SigeOs运算符时,要小心,如解释和更深入的。但是我刚刚在C和C++ 89/11/14中测试过,并且第一个链接答案中提到的两个案例都给出了相同的正确结果。使用代码>输入
表单,如SEI证书页面上的示例所示(这很好),说到
大小
,请注意。
temp = input[0] >> (4 * (i - 1));
/*! \brief Convert nibble (lower 4 bits) to HEX value to avoid using standard libraries.
 */
static inline __attribute__((always_inline, const)) char
NibbleToHex(uint8_t nibble)  {
    return ((nibble <= 9) ? ('0' + nibble) : ('A' + nibble - 10));
}

static void HexToAscii(const uint8_t *input, char *output, uint8_t size) {
    while (size--) {
        *(output++) = NibbleToHex((*input) >> 4u);
        *(output++) = NibbleToHex((*input) & 0x0Fu);
        input++; /*< Move to the next byte. */
    }
}

uint8_t ReferenceNumber[8] = {0x30, 0x40, 0x60, 0x50, 0x80, 0x60, 0x75, 0x95};
HexToAscii(ReferenceNumber, output, sizeof(ReferenceNumber) / sizeof(ReferenceNumber[0]));