Почти завершен десятичный перевод в любую базовую функцию преобразования, не могу понять, как реализовать шестнадцатеричное преобразование

#c

#c

Вопрос:

Я почти закончил с последним методом моего проекта, но я просто не могу понять, как преобразовать десятичную дробь в шестнадцатеричную. Мой код ниже

 int main() {
  printf("Binary to decimal: %sn", decToBase(2, 25));
  printf("Octal to decimal: %sn", decToBase(8, 111));
  printf("Hexidecimal to decimal: %sn", decToBase(16, 248));
}

char* decToBase(int base, int dec) {
  char* temp = (char*)malloc(32*sizeof(char));
  char* ret = (char*)malloc(32*sizeof(char));

  int i = 0;
  while(dec > 0) {
    temp[i] = (dec % base);

    if(temp[i] < 58)
      temp[i]  = '0';
    else
      temp[i]  = 'a';

    dec = dec / base;
    i  ;
  }

  int end = strlen(temp)-1;

  for (i = 0; i < strlen(temp); i  ) {
    ret[i] = temp[end];
    end--;
  }

  free(temp);
  return ret;
}
  

когда я запускаю это на своей машине, я получаю следующее в качестве вывода:

 Binary to decimal: 11001
Octal to decimal: 157
Hexidecimal to decimal: ?8
  

Может ли кто-нибудь указать, почему, когда я выполняю шестнадцатеричное преобразование, я получаю знак вопроса вместо буквы? Спасибо!

Комментарии:

1. Что это такое: temp[i] < 58 ?

2. Используйте отладчик для пошагового выполнения вашего кода оператор за оператором при мониторинге переменных и их значений.

3. Также не забывайте, что char строки в C действительно называются байтовыми строками с нулевым завершением . Я не вижу, чтобы вы завершали свои строки.

Ответ №1:

Этот блок неверен:

     if(temp[i] < 58)
      temp[i]  = '0';
    else
      temp[i]  = 'a';
  

58 это код ASCII для символа после 9 . Но temp[i] не содержит кода ASCII, он содержит числовое значение цифры — вы преобразуете его в коды символов в этом блоке. Поэтому вам следует сравнивать с. 10

И если это не менее 10, вам нужно вычесть 10 при добавлении к 'a' .

Поэтому правильный код должен быть:

     if(temp[i] < 10)
      temp[i]  = '0';
    else
      temp[i]  = 'a' - 10;
  

Вы не добавили нулевой ограничитель в temp , поэтому вы не можете использовать strlen() для определения его длины. Но вам не нужно этого делать, потому i что содержит длину temp .

Таким образом, вы можете изменить второй цикл на:

 int end = i-1;
for (i = 0; end >= 0; i  , end--) {
    ret[i] = temp[end];
}
ret[i] = '';
  

В main() вам нужно присвоить возвращаемое значение decToBase() переменной, чтобы вы могли вызывать free() его после его печати.

 char *binary = decToBase(2, 25);
printf("Binary to decimal: %sn", binary);
free(binary);
  

Комментарии:

1. Большое вам спасибо. Я сделал пару похожих базовых функций преобразования, и я просто потерял след. Спасибо, что помогли мне! : D

2. Не забудьте очистить свою память. Ваша функция выделяет строку и возвращает ее. Вызывающий объект отвечает за освобождение этой памяти, когда она больше не требуется. Ваша программа, написанная в настоящее время, просто пропускает эту память.