Converting Char array to Long in C

32,849

Solution 1

Leaving the burden of matching the endianness with your other function to you, here's one way:

unsigned long int l = pdest[0] | (pdest[1] << 8) | (pdest[2] << 16) | (pdest[3] << 24);

Just to be safe, here's the corresponding other direction:

unsigned char pdest[4];
unsigned long int l;
pdest[0] = l         & 0xFF;
pdest[1] = (l >>  8) & 0xFF;
pdest[2] = (l >> 16) & 0xFF;
pdest[3] = (l >> 24) & 0xFF;

Going from char[4] to long and back is entirely reversible; going from long to char[4] and back is reversible for values up to 2^32-1.

Note that all this is only well-defined for unsigned types.

(My example is little endian if you read pdest from left to right.)

Addendum: I'm also assuming that CHAR_BIT == 8. In general, substitute multiples of 8 by multiples of CHAR_BIT in the code.

Solution 2

You can do:

union {
 unsigned char c[4];
 long l;
} conv;
conv.l = 0xABC;

and access c[0] c[1] c[2] c[3]. This is good as it wastes no memory and is very fast because there is no shifting or any assignment besides the initial one and it works both ways.

Solution 3

A simple way would be to use memcpy:

char * buffer = ...;
long l;
memcpy(&l, buff, sizeof(long));

That does not take endianness into account, however, so beware if you have to share data between multiple computers.

Solution 4

If you mean to treat sizeof (long) bytes memory as a single long, then you should do the below:

char char_arr[sizeof(long)];
long l;
memcpy (&l, char_arr, sizeof (long));

This thing can be done by pasting each bytes of the long using bit shifting ans pasting, like below.

l = 0;
l |= (char_arr[0]);
l |= (char_arr[1] << 8);
l |= (char_arr[2] << 16);
l |= (char_arr[3] << 24);

If you mean to convert "1234\0" string into 1234L then you should

l = strtol (char_arr, NULL, 10); /* to interpret the base as decimal */
Share:
32,849

Related videos on Youtube

AjayR
Author by

AjayR

Having experience in various domains. Expertise in ASP.NET, C#, PHP, ASP, JSP, Nucleus RTOS, GoAhead RTOS, JQuery, Android, Python etc.

Updated on December 07, 2020

Comments

  • AjayR
    AjayR almost 2 years

    This question may looks silly, but please guide me I have a function to convert long data to char array

    void ConvertLongToChar(char *pSrc, char *pDest)
    {
        pDest[0] = pSrc[0];
        pDest[1] = pSrc[1];
        pDest[2] = pSrc[2];
        pDest[3] = pSrc[3];
    }
    

    And I call the above function like this

    long lTemp = (long) (fRxPower * 1000);
    ConvertLongToChar ((char *)&lTemp, pBuffer);
    

    Which works fine. I need a similar function to reverse the procedure. Convert char array to long. I cannot use atol or similar functions.

  • josesuero
    josesuero over 11 years
    It is also, according to the C++ standard, undefined behavior. :)
  • Engineer
    Engineer almost 8 years
    @jalf This is a C question.
  • josesuero
    josesuero almost 8 years
    @NickWiggill fair enough. It is also, according to the C standard, undefined behavior. :)
  • Vinicius Kamakura
    Vinicius Kamakura almost 8 years
    this is not UB under gcc and MS compiler I am pretty sure. It probably is by the C std.
  • underscore_d
    underscore_d almost 5 years
    ^ What compilers do isn't actually informative at all about what the Standard says, though you happened to be correct anyway. @jalf No, C made type-punning via a union well-specified in C99 onwards: stackoverflow.com/questions/11639947/… C++ did not inherit this, however.
  • Antti Haapala -- Слава Україні
    Antti Haapala -- Слава Україні almost 5 years
    and this is wrong, aliasing error and possible undefined behaviour from wrong alignment
  • Antti Haapala -- Слава Україні
    Antti Haapala -- Слава Україні almost 5 years
    and this is wrong, aliasing error and possible undefined behaviour from wrong alignment
  • Beezer
    Beezer almost 2 years
    I tried your example but it did not work for me. What did, was something very similar: char* vIn = "0"; long vOut = strtol(vIn,NULL,10);
  • Etienne de Martel
    Etienne de Martel almost 2 years
    @Beezer That does a very different thing: your method parses text into a number, while mine interprets the bytes of a buffer as a long. These are different problems.

Related