Why is strtol() returning 0x7fffffff instead of the expected 0xAABBCCDD?

huangapple go评论65阅读模式
英文:

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 &lt;stdlib.h&gt;
int main(){
    long i = 0xAABBCCDD;// 0x AABBCCDD in debugger window

    char number[] = &quot;AABBCCDD EEFF&quot;;
    char* p;
    long var = strtol ( number, &amp;p, 16 );// 0x 7FFF FFFF
    perror ( &quot;?:&quot; ); // ?:: Result too large
}

I tried char number[] = &quot;AABBCC EEFF&quot;; 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 strtolstrtollstrtoulstrtoull函数返回已转换的值,如果无法进行转换,则返回零。如果正确的值超出了可表示值的范围,则根据值的返回类型和符号,返回LONG_MINLONG_MAXLLONG_MINLLONG_MAXULONG_MAXULLONG_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 &lt;stddef.h&gt;
#include &lt;stdio.h&gt;

int main( void )
{
	printf( &quot;%#X\n&quot;, 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 &lt;inttypes.h&gt; 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, &amp;p, 16 );

Or if you want to deal with signed integers then use function strtoll.

huangapple
  • 本文由 发表于 2023年6月1日 18:50:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76381127.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定