Converting Char array to Long in C
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 */
Related videos on Youtube

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, 2020Comments
-
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 over 11 yearsIt is also, according to the C++ standard, undefined behavior. :)
-
Engineer almost 8 years@jalf This is a C question.
-
josesuero almost 8 years@NickWiggill fair enough. It is also, according to the C standard, undefined behavior. :)
-
Vinicius Kamakura almost 8 yearsthis is not UB under gcc and MS compiler I am pretty sure. It probably is by the C std.
-
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 -- Слава Україні almost 5 yearsand this is wrong, aliasing error and possible undefined behaviour from wrong alignment
-
Antti Haapala -- Слава Україні almost 5 yearsand this is wrong, aliasing error and possible undefined behaviour from wrong alignment
-
Beezer almost 2 yearsI 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 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.