// msvc 17.3.5
// sizeof (long) : 4
#include <stdlib.h>
int main(){
long i = 0xAABBCCDD;// 0x AABBCCDD in debugger window
char number[] = "AABBCCDD EEFF";
char* p;
long var = strtol ( number, &p, 16 );// 0x 7FFF FFFF
perror ( "?:" ); // ?:: Result too large
}
I tried char number[] = "AABBCC EEFF";
and it works fine.
I expect 0xAABBCCDD
inside var
instead 0x7fffffff
.
What is wrong?
From the C Standard (7.22.1.4 The strtol, strtoll, strtoul, and strtoull functions)
8 The strtol, strtoll, strtoul, and strtoull functions return the converted value, if any. If no conversion could be performed, zero is returned. If the correct value is outside the range of representable values, LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX, ULONG_MAX, or ULLONG_MAX is returned (according to the return type and sign of the value, if any), and the value of the macro ERANGE is stored in errno.
The positive hexadecimal constant 0xAABBCCDD
can not be represented in an object of the signed type long int
provided that sizeof( long int )
is equal to 4
.
For example try this demonstration program
#include <stddef.h>
#include <stdio.h>
int main( void )
{
printf( "%#X\n", LONG_MAX );
}
The program output is
0X7FFFFFFF
Note: as in this case sizeof( long )
is equal to sizeof( unsigned int )
and the value is representable in an object of the type unsigned int
there is used the conversion specifier X
. Otherwise you need to include header <inttypes.h>
and to use a macro as for example PRIX32
.
As you can see LONG_MAX
(the maximum positive value that can be stored in an object of the type long int
) is less than the positive hexadecimal constant 0xAABBCCDD
.
Instead of using the function strtol
use function strtoul
unsigned long var = strtoul ( number, &p, 16 );
Or if you want to deal with signed integers then use function strtoll
.