英文:
Why is strtol() returning 0x7fffffff instead of the expected 0xAABBCCDD?
问题
// msvc 17.3.5
// sizeof (long) : 4
#include <stdlib.h>
int main(){
long i = 0xAABBCCDD;// 0x AABBCCDD 在调试器窗口中
char number[] = "AABBCCDD EEFF";
char* p;
long var = strtol ( number, &p, 16 );// 0x 7FFF FFFF
perror ( "?:"); // ?:: 结果过大
}
我尝试了 char number[] = "AABBCC EEFF";
,它可以正常工作。
我期望 var
中是 0xAABBCCDD
而不是 0x7fffffff
。
哪里出了问题?
英文:
// 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?
答案1
得分: 3
从C标准(7.22.1.4中的strtol、strtoll、strtoul和strtoull函数)
8 strtol、strtoll、strtoul和strtoull函数返回已转换的值,如果无法进行转换,则返回零。如果正确的值超出了可表示值的范围,则根据值的返回类型和符号,返回LONG_MIN、LONG_MAX、LLONG_MIN、LLONG_MAX、ULONG_MAX或ULLONG_MAX,并将宏ERANGE的值存储在errno中。
正的十六进制常数0xAABBCCDD
无法在long int
类型的对象中表示,前提是sizeof(long int)
等于4
。
例如,尝试这个演示程序
#include <stddef.h>
#include <stdio.h>
int main(void)
{
printf("%#X\n", LONG_MAX);
}
程序输出为
0X7FFFFFFF
注意:在这种情况下,sizeof(long)
等于sizeof(unsigned int)
,并且该值可以在unsigned int
类型的对象中表示,因此使用了转换说明符X
。否则,您需要包含头文件<inttypes.h>
并使用一个宏,例如PRIX32
。
正如您所看到的,LONG_MAX
(可以存储在long int
类型对象中的最大正值)小于正的十六进制常数0xAABBCCDD
。
而不是使用函数strtol
,可以使用函数strtoul
unsigned long var = strtoul(number, &p, 16);
或者,如果您想处理有符号整数,那么可以使用函数strtoll
。
英文:
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
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论