简体   繁体   中英

Data types conversion (unsigned long long to char)

Can anyone tell me what is wrong with the following code?

__inline__
char* ut_byte_to_long (ulint nb) {

   char* a = malloc(sizeof(nb)); 
   int i = 0;
   for (i=0;i<sizeof(nb);i++) {
       a[i] = (nb>>(i*8)) & 0xFF;
   }
   return a; 
}

This string is then concatenated as part of a larger one using strcat . The string prints fine but for the integers which are represented as character symbols. I'm using %s and fprintf to check the result.

Thanks a lot.

EDIT

I took one of the comments below (I was adding the terminating \\0 separately, before calling fprintf , but after strcat . Modifying my initial function...

__inline__
char* ut_byte_to_long (ulint nb) {

   char* a = malloc(sizeof(nb) + 1); 
   int i = 0;
   for (i=0;i<sizeof(nb);i++) {
       a[i] = (nb>>(i*8)) & 0xFF;
   }
   a[nb] = '\0' ; 
   return a; 
}

This sample code still isn't printing out a number...

char* tmp;
tmp = ut_byte_to_long(start->id);

fprintf(stderr, "Value of node is %s \n ", tmp);

strcat is expecting a null byte terminating the string.

Change your malloc size to sizeof(nb) + 1 and append '\\0' to the end.

You have two problems.

The first is that the character array a contains numbers, such as 2 , instead of ASCII codes representing those numbers, such as '2' (=50 on ASCII, might be different in other systems). Try modifying your code to

a[i] = (nb>>(i*8)) & 0xFF + '0';

The second problem is that the result of the above computation can be anything between 0 and 255, or in other words, a number which requires more than one digit to print.

If you want to print hexadecimal numbers (0-9, AF), two digits per such computation will be enough, and you can write something like

a[2*i + 0] = int2hex( (nb>>(i*8)) & 0x0F );   //right hexa digit
a[2*i + 1] = int2hex( (nb>>(i*8+4)) & 0x0F ); //left hexa digit

where

char int2hex(int n) {
  if (n <= 9 && n >= 0)
    return n + '0';
  else
    return (n-10) + 'A';
}

if you dont want to use sprintf(target_string,"%lu",source_int) or the non standard itoa() , here is a version of the function that transform a long to a string :

__inline__
char* ut_byte_to_long (ulint nb) {
    char* a = (char*) malloc(22*sizeof(char));  
    int i=21;
    int j;
    do
    {
        i--;
        a[i] = nb % 10 + '0';
        nb = nb/10; 
    }while (nb > 0);
    // the number is stored from a[i] to a[21]

    //shifting the string to a[0] : a[21-i]
    for(j = 0 ; j < 21 && i < 21 ; j++ , i++)
    {
        a[j] = a[i];
    }
    a[j] = '\0';
    return a;
}

I assumed that an unsigned long contain less than 21 digits. (biggest number is 18,446,744,073,709,551,615 which equals 2^64 − 1 : 20 digits)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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