【问题标题】:Convert char* in hex to normal char*?将十六进制的 char* 转换为普通的 char*?
【发布时间】:2014-03-11 23:18:12
【问题描述】:

我有这个功能:

char *ctohex(char *str){
    int i=0, len;
    len = strlen(str);
    char *final = malloc(len*2*sizeof(char)+1);
    while(len--){
         sprintf(final+i*2, "%02X", str[i]);
         i++;
    }
    return final;
}

现在我想要一个反向函数,从十六进制到普通字符,这可能吗?对不起我的英语。没有人给我一个好的答案,也许我解释错了。

我在我的函数中有这个输入: JOAO 输出是: 4A4F414F

我想把4A4F414F 放回JOAO

【问题讨论】:

    标签: c string hex


    【解决方案1】:

    几乎是原始ctohex()的简单反转

    #include <ctype.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char *hextoc(const char *str) {
      size_t i, j, len;
      len = strlen(str);
    
      // If the length is not even
      if (len % 2)
        return NULL;
    
      char *final = malloc(len/2 + 1);
      if (final == NULL)
        return NULL;
    
      j = 0;
      for (i = 0; i < len; i += 2) {
        if (!isxdigit((unsigned char) str[i])
                || !isxdigit((unsigned char) str[i+1])) {
          free(final);
          return NULL;
        }
        unsigned x;
        sscanf(&str[i], "%2X", &x);
        final[j++] = (char) x;
      }
      final[j] = '\0';
      return final;
    }
    
    int main() {
      return puts(hextoc("4A4F414F"));
      // prints JOAO
    }
    

    ctohex(char *str) 有问题。当str[i]

    // sprintf(final+i*2, "%02X", str[i]);
    sprintf(final+i*2, "%02X", str[i] & 0xFF);
    // or
    sprintf(final+i*2, "%02hhX", str[i]);  // Current C compilers
    

    【讨论】:

      【解决方案2】:

      当然可以从十六进制转换为普通字符。

      一次检查 2 个字符并决定要打印的字符

      if (char1 == '0' && char2 == '0') putchar(0x00);
      if (char1 == '0' && char2 == '1') putchar(0x01);
      /* ... */
      if (char1 == '4' && char2 == '2') putchar(0x42); /* ASCII B */
      /* ... */
      if (char1 == 'f' && char2 == 'f') putchar(0xff);
      

      虽然有更有效的方法:)

      【讨论】:

        【解决方案3】:

        在每个十六进制数上使用带有 base=16 的 strtol()

        【讨论】:

          【解决方案4】:

          您的主要问题是您转换为十六进制并没有真正做任何事情,因为您将每个数字转换为其等效的十六进制,这什么也没做。十进制的 5 也是十六进制的 5。您所做的只是在每个数字之间添加 0(“5432”->“05040302”)

          如果您要求在字符串中取一个由其十六进制值表示的数字并将其作为十进制值放入字符串中,例如“0x5A8C” -> “23180”,那么这就是你要做的:

              char *convert( char * instr )
              {
                  char outstr[50] = {0};
                  int tmpval = 0;
                  sscanf( instr, "%x", tmpval );
                  sprintf( outstr, "%d", tmpval );
                  char * retval;
                  strcpy( retval, outstr );
                  return retval;
              }
          

          使用 sscanf() 的好处是 sscanf 将对待 0x5a0X5A5a5A 相同。

          如果您只是想将 ctohex() 函数生成的任何字符串转换回,那么您只需将每个其他数字复制到一个新字符串中。

          如果要将十六进制数字序列转换为十进制值,则必须指定要转换的数字位数。你想要“5A8C”->“510812”还是想要“90140”?

          【讨论】:

            猜你喜欢
            • 2012-02-24
            • 2013-05-07
            • 2011-11-27
            • 2011-05-25
            • 2015-06-04
            • 2013-09-01
            • 2012-07-23
            • 1970-01-01
            • 2018-11-07
            相关资源
            最近更新 更多