简体   繁体   English

如何在 C 中将十六进制转换为二进制并将二进制输出为 char 数组?

[英]How to convert Hex to binary in C and output binary as a char array?

I'm trying to write a function that converts hex char into binary array so it's easy to read all the ones and zeros one by one.我正在尝试编写一个将十六进制字符转换为二进制数组的函数,因此很容易一一读取所有的一和零。 Am having problems with the code.我的代码有问题。 I currently have written the code below.我目前已经编写了下面的代码。 It gives me an error saying that it returns an address of a local variable, even though I tried to make it return a char .它给了我一个错误,说它返回一个局部变量的地址,即使我试图让它返回一个char

char *hex_to_bin(const char input[]) {
    char output[] = "";
    int i = 0;
    while (input[i]) {
        switch (input[i]) {
          case '0':
            strcat(output, "0000");
            break;
          case '1':
            strcat(output, "0001");
            break;
          case '2':
            strcat(output, "0010");
            break;
          case '3':
            strcat(output, "0011");
            break;
          case '4':
            strcat(output, "0100");
            break;
          case '5':
            strcat(output, "0101");
            break;
          case '6':
            strcat(output, "0110");
            break;
          case '7':
            strcat(output, "0111");
            break;
          case '8':
            strcat(output, "1000");
            break;
          case '9':
            strcat(output, "1001");
            break;
          case 'A':
            strcat(output, "1010");
            break;
          case 'B':
            strcat(output, "1011");
            break;
          case 'C':
            strcat(output, "1100");
            break;
          case 'D':
            strcat(output, "1101");
            break;
          case 'E':
            strcat(output, "1110");
            break;
          case 'F':
            strcat(output, "1111");
            break;
          case 'a':
            strcat(output, "1010");
            break;
          case 'b':
            strcat(output, "1011");
            break;
          case 'c':
            strcat(output, "1100");
            break;
          case 'd':
            strcat(output, "1101");
            break;
          case 'e':
            strcat(output, "1110");
            break;
          case 'f':
            strcat(output, "1111");
            break;
        }
        i++;
    }
    return output;
}

Perhaps this is a silly approach, but I only recently picked up C.也许这是一种愚蠢的方法,但我最近才开始使用 C。

There are 2 major problems in your code:您的代码中有两个主要问题:

  • char output[] = ""; defines an array of char just large enough to hold the empty string.定义一个足够大的char数组来容纳空字符串。 For you purpose, you should allocate an array with a size 4 * strlen(input) + 1出于您的目的,您应该分配一个大小为4 * strlen(input) + 1的数组
  • return output; returns the address of a local object, which will become invalid as soon as the function returns.返回本地对象的地址,一旦函数返回,该地址将变为无效。 You could instead allocate memory from the heap with malloc() and return the pointer.您可以改为使用malloc()从堆中分配内存并返回指针。 The caller will be responsible for freeing this object.调用者将负责释放该对象。

Here is a modified version:这是修改后的版本:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *hex_to_bin(const char input[]) {
    char *output = malloc(strlen(input) * 4 + 1);
    if (output != NULL) {
        char *p = output;
        *p = '\0';
        for (size_t i = 0; input[i]; i++) {
            switch (input[i]) {
              case '0':
                strcpy(p, "0000");
                break;
              case '1':
                strcpy(p, "0001");
                break;
              case '2':
                strcpy(p, "0010");
                break;
              case '3':
                strcpy(p, "0011");
                break;
              case '4':
                strcpy(p, "0100");
                break;
              case '5':
                strcpy(p, "0101");
                break;
              case '6':
                strcpy(p, "0110");
                break;
              case '7':
                strcpy(p, "0111");
                break;
              case '8':
                strcpy(p, "1000");
                break;
              case '9':
                strcpy(p, "1001");
                break;
              case 'A':
              case 'a':
                strcpy(p, "1010");
                break;
              case 'B':
              case 'b':
                strcpy(p, "1011");
                break;
              case 'C':
              case 'c':
                strcpy(p, "1100");
                break;
              case 'D':
              case 'd':
                strcpy(p, "1101");
                break;
              case 'E':
              case 'e':
                strcpy(p, "1110");
                break;
              case 'F':
              case 'f':
                strcpy(p, "1111");
                break;
              default:
                p[0] = input[i];
                p[1] = '\0';
                break;
            }
            p += strlen(p);
        }
    }
    return output;
}

int main() {
    char *p = hex_to_bin("n = DeadBeef\n");
    printf("%s\n", p);
    free(p);
    return 0;
}

Code fails as it attempts to return an undersized local array.代码失败,因为它试图返回一个过小的本地数组。 output[] is too small and local arrays are invalid once the function ends. output[]太小,函数结束后局部数组无效。

Instead, consider passing in a destination array.相反,请考虑传入一个目标数组。

// Return NULL on error
char *hex_to_bin(size_t size, char *dest, const char input[]) {
  // Enough room? 
  size_t len = strlen(input);
  if (dest == NULL || len * 4 + 1 < size) {
    return NULL;
  }

  char *s = dest;
  size_t i;
  // Iterate until a non-hex digit found ....
  for (i = 0; isxdigit((unsigned char) input[i]); i++) {
    // Rather than a huge switch table, how about scanning a string of length 1?
    unsigned digit;
    sscanf((char[2]){ input[i], '\0'}, "%x", &digit);
    // Now convert to binary 
    for (unsigned mask = 8; mask; mask >>= 1) {
      *s++ = mark & digit ? '1' : '0';
    }
  }
  *s = '\0';
  if (input[i] != '\0') { // Was a non-hex digit found?
    return NULL; 
  }
  return dest;
}                      

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM