在没有(sprintf / printf库)的情况下将整数转换为C中的十六进制字符串

时间:2017-06-14 15:51:14

标签: c printf

我有这些输入变量:

 uint16 temperature = 0x1f12;
 uint8 array[8] = {0,0,0,...0}

我想要

array8[0] = '1';
array8[1] = 'f';
array8[2] = '1';
array8[3] = '2';
array8[4] = '\0';
array8[5] = '\0';
array8[6] = '\0';
array8[7] = '\0';

但是,对于内存问题(我使用微控制器!)我需要避免使用sprintf,printf,puts等功能。

我该怎么办?

致以最诚挚的问候,

3 个答案:

答案 0 :(得分:1)

使用递归一次确定1个十六进制数字。

// print digit at the end and return the next address
static char *itohexa_helper(char *dest, unsigned x) {
  if (x >= 16) {
    dest = itohexa_helper(dest, x/16);
  }
  *dest++ = "0123456789abcdef"[x & 15];
  return dest;
}

char *itohexa(char *dest, unsigned x) {
  *itohexa_helper(dest, x) = '\0';
  return dest;
}

int main(void) {
  char array[8];
  uint16_t temperature = 0x1f11;
  puts(itohexa(array, temperature));
  puts(itohexa(array, 0));
  puts(itohexa(array, 0x1234567));
  puts(itohexa(array, UINT_MAX & 0xFFFFFFF));
}

输出

1f11
0
1234567
fffffff

答案 1 :(得分:1)

此代码在堆栈中仅使用8个额外字节(int i, j)。

int i;
for (i = 0; i < 8; i++) {
    array[7 - i] = temperature % 16;
    temperature /= 16;

    if (temperature == 0)
        break;
}

if (i == 8)
    i--;

int j;
for (j = 0; j <= i; j++)
    array[j] = array[7 - i + j];
for (j = i + 1; j < 8; j++)
    array[j] = 0;

for (j = 0; j < 8; j++)
    if (array[j] < 10)
        array[j] += '0';
    else
        array[j] += 'a' - 10;

此代码首先将temperature = 0x1f12转换为array[8] = { 0, 0, 0, 0, 1, 15, 1, 2}

然后移动array的元素,使其变为array[8] = { 1, 15, 1, 2, 0, 0, 0, 0 }

然后将数字转换为相应的字符:array[8] = { '1', 'f', '1', '2', '0', '0', '0', '0' }

另请注意,这是条件

    if (i == 8)
        i--;
永远不会满足

,因为在第一个for循环中,断点条件总是足够的,即使温度> = 0x10000000也是如此。它就在那里,希望它可以帮助别人理解这段代码。

答案 2 :(得分:0)

int convert()
{
 uint16_t temperature = 0x1f11;
 uint8_t array[8] = {0,0,0,0,0,0,0,0};

 int i = 0;

 for(i = 0; i < 8; i++){
    array[i] = (0xf000 & temperature) >> 12 ;
    temperature <<= 4;
    printf("array[%d] = %x\n", i ,array[i]);
 }
 return(0);
}