将带有前导零的二进制字符串转换为十六进制字符串

时间:2014-11-02 12:48:20

标签: c

我要从文本文件中读取代码(二进制),该文件将包含“000101”或“100010”等数据。然后我进一步用这个二进制字符串连接2位。我遇到了导致零的问题,我无法跳过。我一直试图通过首先将二进制字符串转换为int(使用atoi())然后转换为十六进制字符串来实现。但是如果使用该函数,则使用前导零,它会截断前导零。我在这里搜索过,但给出的解决方案不是C语言。有没有直接的方法来做到这一点,或者我将不得不追踪一切?提前致谢。 这是我的函数,它将int作为输入,然后将其转换为十六进制字符串

void toHex(int n, char str[]) /* Function to convert binary to hexadecimal. */
{
int i=0,decimal=0, rem;
char temp[2];
while (n!=0)
{
    decimal += (n%10)*pow(2,i);
    n/=10;
    ++i;
}

/* At this point, variable decimal contains binary number in decimal format. */
i=0;
while (decimal!=0)
{
    rem=decimal%16;
    switch(rem)
    {
        case 10:
          str[i]='A';
          break;
        case 11:
          str[i]='B';
          break;
        case 12:
          str[i]='C';
          break;
        case 13:
          str[i]='D';
          break;
        case 14:
          str[i]='E';
          break;
        case 15:
          str[i]='F';
          break;
        default:
          str[i]=rem+'0';
          break;
    }
    ++i;
    decimal/=16;
}
str[i]='\0';
strrev(str); // Function to reverse string.
if(strlen(str)==1)
{
    temp[0] = '0';
    temp[1] = str[0];
    temp[2] = '\0';
    strcpy(str,temp);
}
else if(strlen(str)==0)
{
    temp[0] = '0';
    temp[1] = '0';
    temp[2] = '\0';
    strcpy(str,temp);
}
}

2 个答案:

答案 0 :(得分:1)

  1. 获取二进制数字的数量(在调用atoi之前)

    size_t binlen = strlen(input);
    
  2. 获取要输出的十六进制数字的数字(仅binlen/4四舍五入)

    size_t hexlen = ((binlen % 4 ? binlen+4 : binlen) / 4);
    
  3. 将整数打印为十六进制,并使用正确的前导零数

    sprintf(str, "%0.*x", hexlen, n);
    

    NB。你应该真正传递输出缓冲区的长度,而是使用snprintf代替......

答案 1 :(得分:0)

您不应该首先将数字转换为int(构建decimal的循环)。

相反,您应该编写一个单独的函数,它使用四个字符表示二进制数,并生成一个十六进制字符。然后,您可以将目标函数实现为对此函数的一系列调用,一次运行四个字符。

这种方法的唯一技巧是你需要处理二进制字符串的长度不能被4整除的情况。在这种情况下,你需要用零填充字符串的初始部分。

以下是如何实现将四个字符转换为单个十六进制数字的函数:

char binToHexDigit(const char bin[4]) {
    int digit = (bin[0] == '1' ? 8 : 0)
              | (bin[1] == '1' ? 4 : 0)
              | (bin[2] == '1' ? 2 : 0)
              | (bin[3] == '1' ? 1 : 0);
    return (digit < 10 ? '0' : ('A'-10)) + digit;
}

Demo

注意这个函数如何通过利用数字0..9和字母A..F在UNICODE,ASCII和EBCDIC中按顺序排列的事实来避免switch语句,因此您可以将数字转换为数字字符使用简单的添加。